0

I'm sort an array based on the keys in another array. If they find a match, it would move those items to the front of the array. But I can't think of a clean way to do this.

let myArray = [
  { id: 'a', name: 'Mal' },
  { id: 'b', name: 'Wash'},
  { id: 'c', name: 'Inara'},
  { id: 'd', name: 'Jayne'},
  ]

let sortArray = [
  { id: 'b' },
  { id: 'c' },
  { id: 'x' },
]

/* Expected result
myArray = [
  { id: 'b', name: 'Wash'},
  { id: 'c', name: 'Inara'},
  { id: 'a', name: 'Mal' },
  { id: 'd', name: 'Jayne'},
  ]
/*

Does anyone know a way to do this without just looping through it a bunch of times? Thanks

2 Answers 2

2

You could create a Map which maps each id in sortArray to its index. Use this priority map object to sort the first array.

const array = [{ id: 'a', name: 'Mal' }, { id: 'b', name: 'Wash'}, { id: 'c', name: 'Inara'}, { id: 'd', name: 'Jayne'}],
     sortArray = [{ id: 'b' }, { id: 'c' }, { id: 'x' }],
     map = new Map( sortArray.map((o, i) => [o.id, i]) )

array.sort((a,b) => 
  ( map.has(b.id) - map.has(a.id) ) || ( map.get(a.id) - map.get(b.id) )
)

console.log(array)

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

Comments

1

You could take an object ffor the wanted order of the items and a default value for unknown items.

let array = [{ id: 'a', name: 'Mal' }, { id: 'b', name: 'Wash'}, { id: 'c', name: 'Inara'}, { id: 'd', name: 'Jayne'}],
    sortArray = [{ id: 'b' }, { id: 'c' }, { id: 'x' }],
    order = Object.fromEntries(sortArray.map(({ id }, i) => [id, i + 1]));

array.sort(({ id: a }, { id: b }) =>
    (order[a] || Number.MAX_VALUE) - (order[b] || Number.MAX_VALUE)
);

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.