I have an array of objects. From this array I want to create a sorted map by the key foo
. The values shall be arrays with the corresponding objects, sorted by the key bar
.
// input data
const arr = [{'foo': 42, 'bar': 7}, {'foo': 1, 'bar': 2}, {'foo': 1, 'bar': 1}];
// insert magic here
// This is the result (not sure how to correctly display a map)
{
1 -> [{'foo': 1, 'bar': 1}, {'foo': 1, 'bar': 2}],
42 -> [{'foo': 42, 'bar': 7}]
}
It’s not too difficult to find a working solution. But I’m looking for a simple and fast solution, preferrably a one-liner. How can this be done?
My current endeavors
Currently I’m stuck with this line of code. It creates a map with arrays. Is there a way to at least include the sorting functionality for the keys in there? I could then do a second step and sort the arrays separately.
const result = new Map(arr.map(i => [i.foo, i]));
2
Answers
Step by step:
Use
Array.prototype.reduce()
turn the array into a map.Use
Object.values()
,Array.prototype.forEach()
andArray.prototype.sort()
to sort all arrays.You can also make it a one-liner and still use built-in methods, but performance would be worse as this is creating intermediate objects and arrays and sorting the arrays continuously (which is totally unnecessary):
If you need the keys of the map to be sorted, I recommend you use an actual
Map
instead of using a regularObject
. This is what the MDN Map docs say about this:You might also want to take a look at this other question (pay attention to the date of the answers): Does ES6 introduce a well-defined order of enumeration for object properties?
Therefore, you just need to sort the array before using reduce, and replace the
initialValue
param withnew Map()
:Just keep in mind the keys in the
Map
are ordered by insertion order, so if you have keysA
,B
andC
and addD
later,D
will be the last one (4th) not the first.A fast one-liner: