How to Sort an Array of Objects Based on the Ordering of Another Array

Javascript - sort array based on another array

One-Line answer.

itemsArray.sort(function(a, b){  
return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});

Or even shorter:

itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));

Sort an array of objects based on another array of ids

Ramda really shines for these types of problems.

Where the size of the data is small, we can use a simple reduce function, and indexOf helper.

// match id of object to required index and insert
var sortInsert = function (acc, cur) {
var toIdx = R.indexOf(cur.id, a);
acc[toIdx] = cur;
return acc;
};

// point-free sort function created
var sort = R.reduce(sortInsert, []);

// execute it now, or later as required
sort(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]

This works well for small(ish) data sets but the indexOf operation on every iteration through the reduction is inefficient for large data sets.

We can remedy this by tackling the problem from the other side, lets use groupBy to group our objects by their id, thus creating a dictionary lookup (much better!). We can then simply map over the required indexes and transform them to their corresponding object at that position.

And here is the solution using this approach:

var groupById = R.groupBy(R.prop('id'), b);

var sort = R.map(function (id) {
return groupById[id][0];
});

sort(a);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]

Finally, this is yet another solution, which is very succinct:

R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);
// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]

I love the way you can compose functions with behaviour and separate the algorithm from the data upon which it acts using Ramda. You end up with very readable, and easy to maintain code.

Sort Array of Objects based on position of value in another Array of Strings

You can loop the correct_order array and filter the unsorted array by using the js filter function. If filter match push to an new array.

const UNSORTED = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];

const CORRECT_ORDER = ['Animal','Plant','Sand','Grass'];

let sorted = []
CORRECT_ORDER.forEach(k => {
let n = UNSORTED.filter(obj => {
return obj.Type === k
})
if (n.length > 0) {
sorted.push(n);
}

})

console.log(sorted);

Sort array of object by another array of object

You could use map function:

const tempArray = one.map(x => two.find(item => item.name === x.name));

Alternatively, if you are not striving for brevity:

const nameToPosMap = Object.fromEntries(one.map((x, idx) => [x.name, idx]));
two.sort((i1, i2) => nameToPosMap[i1.name] - nameToPosMap[i2.name])

This may be faster as it avoids repeated find calls.

Sort array of objects based on best matching another array

You can base your logic on the size of the Set that contains distinct elements from both template and items. The smaller the Set, the more common items:

const template = ['A', 'B', 'C'];

const source = [
{ items: ['B', 'D', 'E'] },
{ items: ['E', 'L', 'Y'] },
{ items: ['G', 'B', 'A'] },
{ items: ['C', 'B', 'A'] }
];

const target = source
.map(({items}) => ({items, size: new Set([...items, ...template]).size}))
.sort((a, b) => a.size - b.size);

console.log(target);

Javascript sort array of objects based on another array

that ?

const arr1 = 
[ { id: 21, name: 'Joey', vehicle: 'car' }
, { id: 6, name: 'Kevin', vehicle: 'car' }
, { id: 10, name: 'Luis', vehicle: 'van' }
]

const arr2 =
[ { id: 6, name: 'Kevin' }
, { id: 21, name: 'Joey' }
, { id: 10, name: 'Luis' }
]


// Arr1 ordered..
const arr1_ord = arr2.map(a2=> arr1.find(x=>x.id===a2.id))

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

Sort aray of objects by another array of objects reference

You can filter your settings list based on the display property and then use Array.map to return a list of objects in products that match the category:

const products = [
{id: 0, name: 'Chocolate', category: 'Sweet'},
{id: 1, name: 'Almendras', category: 'Fruit'},
{id: 2, name: 'Nueces', category: 'Fruit'},
{id: 3, name: 'Mermelada', category: 'Jam'},
{id: 4, name: 'Alfajor', category: 'Sweet'},
{id: 5, name: 'Queso', category: 'UwU'},
{id: 6, name: 'Arandanos', category: 'Fruit'},
{id: 7, name: 'Maracuya', category: 'Fruit'}
];

const settings = [
{ name: 'Fruit', display: true },
{ name: 'Jam', display: false },
{ name: 'Sweet', display: true },
{ name: 'UwU', display: true }
];

const result = settings
.filter(c => c.display)
.map(c => products.filter(o => o.category == c.name));

console.log(result);

Sort an array in the same order of another array

Use indexOf() to get the position of each element in the reference array, and use that in your comparison function.

var reference_array = ["ryan", "corbin", "dan", "steven", "bob"];var array = ["bob", "dan", "steven", "corbin"];array.sort(function(a, b) {  return reference_array.indexOf(a) - reference_array.indexOf(b);});console.log(array); // ["corbin", "dan", "steven", "bob"]

Sort array of objects based on another array of objects key

You can try this, it finds the first elem in array2 matching the name, in order, from the array1.. removes it from array2 and then adds it to the sortedArray2.

const array1 = [
{
"name": "B",
"order": 1
},
{
"name": "C",
"order": 2
},
{
"name": "D",
"order": 3
},
{
"name": "B",
"order": 4
},
{
"name": "A",
"order": 5
}
]

const array2 = [
{
"name": "B",
"order": 1,
"id": 3638
},
{
"name": "B",
"order": 1,
"id": 3661
},
{
"name": "C",
"order": 2,
"id": 3658
},
{
"name": "D",
"order": 3,
"id": 3659
},
{
"name": "A",
"order": 5,
"id": 3636
}
]

const sortedArray2 = []

for(const item of array1) {
sortedArray2.push(
array2.splice(
array2.findIndex(elem => elem.name === item.name), 1
)
)
}

console.log(sortedArray2)


Related Topics



Leave a reply



Submit