简体   繁体   中英

Sort array of objects based on order of another array of objects

I have two arrays of objects and I need to match the order of one of the arrays with the other. Here's an example:

const outOfOrderArray = [{field: 'foo'}, {field: 'bar'}, {field: 'bazz'}, {field: 'bizz'}];

const arrayInProperOrder = [{field: 'bizz'}, {field: 'bazz'}, {field: 'foo'}, {field: 'bar'}];

What can I do to make the outOfOrderArray match the order of objects in arrayInProperOrder ?

Here is how you can do it in one less loop than the solution of @Faly. There is no need to sort the array. You may just loop over arrayInProperOrder and find matching element from outOfOrderArray so that the latter becomes in order.

 const outOfOrderArray = [{field: 'foo'}, {field: 'bar'}, {field: 'bazz'}, {field: 'bizz'}]; const arrayInProperOrder = [{field: 'bizz'}, {field: 'bazz'}, {field: 'foo'}, {field: 'bar'}]; const newArray = []; arrayInProperOrder.forEach(item => { const original = outOfOrderArray.find(i => i.field === item.field); if (original) { newArray.push(original); } }); console.log(newArray); 

If you need it in place, just assign newArray to outOfOrderArray .

You can create a temp object to store the order and use it as a basis on sort()

Use Infinity as the default value if some field is not found on temp object.

 const outOfOrderArray = [{field: 'foo'}, {field: 'bar'}, {field: 'bazz'}, {field: 'bizz'}]; const arrayInProperOrder = [{field: 'bizz'}, {field: 'bazz'}, {field: 'foo'}, {field: 'bar'}]; //Make a temp object - This will store the order of the field. This nessasary so that no need to search every reiteration on sort() const tempObj = arrayInProperOrder.reduce((c, v, i) => Object.assign(c, {[v.field]: i + 1}), {}); //Sort the array. outOfOrderArray.sort((a, b) => (tempObj[a.field] || Infinity) - (tempObj[b.field] || Infinity)); console.log(outOfOrderArray); 

Doc: sort() , Infinity

You can use array.prototype.sort and array.prototype.findIndex :

 const outOfOrderArray = [{field: 'foo'}, {field: 'bar'}, {field: 'bazz'}, {field: 'bizz'}]; const arrayInProperOrder = [{field: 'bizz'}, {field: 'bazz'}, {field: 'foo'}, {field: 'bar'}]; outOfOrderArray.sort( (a, b) => arrayInProperOrder.findIndex(e => e.field === a.field) - arrayInProperOrder.findIndex(e => e.field === b.field) ); console.log(outOfOrderArray); 

If you care about performance, you can build an object allowing you to get the index by the field value, from arrayInProperOrder array:

 const outOfOrderArray = [{field: 'foo'}, {field: 'bar'}, {field: 'bazz'}, {field: 'bizz'}]; const arrayInProperOrder = [{field: 'bizz'}, {field: 'bazz'}, {field: 'foo'}, {field: 'bar'}]; const indexes = arrayInProperOrder.reduce((m, o, i) => (m[o.field] = i, m), {}); outOfOrderArray.sort( (a, b) => indexes[a.field] - indexes[b.field] ); console.log(outOfOrderArray); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM