-1

I have a following array of objects:

[
  0: {
    id: 1,
    type: 'input'   
  },
  1: {
    id: 2,
    type: 'boolean'   
  },
  2: {
    id: 3,
    type: 'choice'   
  },
  3: {
    id: 1,
    type: 'select'   
  },
]

I want to sort the array element based on the value of type. If type is 'choice' I want to place the element in the last place of array i.e. 4th place. If type is 'boolean', place it in third place. If type is 'select', place it in second place.

I know how to sort an array with numerical values.

arr.sort((a, b) => {
  if (a.type < b.type) return -1
  return a.type > b.type ? 1 : 0
})

I am having problem comparing property values and sorting it.

Please help me. Any help will be highly appreciated.

Regards,

2
  • Consider a separate array that holds types in their desired order, and sort based on their index in that array. Or a hashmap that has type and position. Commented Feb 25, 2020 at 19:17
  • 1
    Um, there is no name property... Commented Feb 25, 2020 at 19:18

2 Answers 2

1

Usually if need to sort an array based on some string property of object you need to create another which represents the order of sort. Then use indexOf and subtract the indexes

const order = ['input', 'select', 'boolean','choice'];

const arr = [
  {
    id: 1,
    type: 'input'   
  },
  {
    id: 2,
    type: 'boolean'   
  },
  {
    id: 3,
    type: 'choice'   
  },
  {
    id: 1,
    type: 'select'   
  },
]

arr.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type));
console.log(arr)

Sign up to request clarification or add additional context in comments.

Comments

1

If you had

const arr = [
  {
    id: 1,
    type: 'input',
    val: 1
  },
  {
    id: 2,
    type: 'boolean',
    val: 3
  },
  {
    id: 3,
    type: 'choice',
    val: 4,
  },
  {
    id: 1,
    type: 'select',
    val: 2
  },
]

then it would be easy: just arr.sort((a, b) => a.val - b.val)

Since you don't have the property val, you can just set it on before:

const typeToValue = {
  input: 1,
  boolean: 3,
  choice: 4,
  select: 2
}
arr.forEach(el => {
  el.val = typeToValue[el.type]
})
arr.sort((a, b) => a.val - b.val)

Maybe you don't want to dirty your elements, notice that el.val == typeToValue[el.type]

Meaning you can write arr.sort((a, b)=>typeToValue[a.type] - typeToValue[b.type])

Finally should you have a sorted array ['input', 'select', 'boolean', 'choice'] you can trivially transform it to typeToValue object via Array.prototype.reduce

const orders = ['input', 'select', 'boolean', 'choice']
const typeToValue = orders.reduce((o, el, i) => (o[el] = i, o), {})

or if you don't like reduce with Object.fromEntries

const typeToValue = Object.fromEntries(orders.map((el, i) => [el, i]))

const arr = [{"id":1,"type":"input"},{"id":2,"type":"boolean"},{"id":3,"type":"choice"},{"id":1,"type":"select"}]
const orders = ['input', 'select', 'boolean', 'choice']
const typeToValue1 = orders.reduce((o, el, i) => (o[el] = i, o), {})
const typeToValue2 = Object.fromEntries(orders.map((el, i) => [el, i]))

// just slice to copy array because sort modify in place
console.log(arr.slice(0).sort((a, b)=>typeToValue1[a.type] - typeToValue1[b.type]))
console.log(arr.slice(0).sort((a, b)=>typeToValue2[a.type] - typeToValue2[b.type]))

2 Comments

Thank You for the detailed answer. :)
you are welcome @SujanShrestha :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.