Reputation: 1875
I have an array of objects
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
and an array
let sorter = ['second', 'third', 'first']
I would like to use lodash
sorting method to sort my objects according to their position in sorter
.
So that the output would be
let mySortedArray = [
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
},
{
id: 'first',
name: 'john',
}
]
Is it possible to do so?
Upvotes: 2
Views: 3231
Reputation: 18515
Since you have an index
array in the case of the sorter
you can _.keyBy
the main array and then use the sorter
to access by index:
let myArray = [ { id: 'first', name: 'john', }, { id: 'second', name: 'Emmy', }, { id: 'third', name: 'Lazarus', } ]
let sorter = ['second', 'third', 'first']
const idMap = _.keyBy(myArray, 'id')
const result = _.map(sorter, x => idMap[x])
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
This should perform better since you only do the idMap once
and then access it by index
.
Upvotes: 0
Reputation: 29009
If you want to sort the array in-place, you don't need Lodash, you can easily do it with vanilla JavaScript
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
let sorter = ['second', 'third', 'first']
//create a lookup table (map) to save looking through the array
const sortLookup = new Map();
//populate with element as key - index as value
sorter.forEach((id, index) => sortLookup.set(id, index));
//sort using the indexes of sorter
myArray.sort((a, b) => sortLookup.get(a.id) - sortLookup.get(b.id))
console.log(myArray)
This is using a Map but the same can easily be accomplished with a plain JavaScript Object {}
. You don't even need to pre-compute the lookup myArray.sort((a, b) => sorter.indexOf(a.id) - sorter.indexOf(b.id))
would give the exact same output but it would mean that instead of traversing sorter
once for a complexity of O(n)
, you potentially have O(n^m)
or O(n^n)
(if both arrays are the same length)
Upvotes: 0
Reputation: 6739
Using lodash you can use _.sortBy
let myArray = [
{
id: 'first',
name: 'john',
},
{
id: 'second',
name: 'Emmy',
},
{
id: 'third',
name: 'Lazarus',
}
]
let sorter = ['second', 'third', 'first']
console.log(_.sortBy(myArray,(i) => {return sorter.indexOf(i.id)}))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
Upvotes: 3
Reputation: 10366
You can achieve this by using map and find:
let myArray = [
{
id: "first",
name: "john"
},
{
id: "second",
name: "Emmy"
},
{
id: "third",
name: "Lazarus"
}
];
let sorter = ["second", "third", "first"];
let mySortedArray = sorter.map(x => myArray.find(y => y.id === x));
console.log(mySortedArray);
Upvotes: 5