Reputation: 19705
I have an array:
{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },
When I do:
let groups = _.groupBy(conso, 'date');
I get the result grouped, but I lose the order, the first element is not 25, it is 10:
{
'10': [
{ date: '10', value: '542' },
{ date: '10', value: '492' },
....
]
}
Is this the wanted behaviour ? If sorting alphabetically, shouldn't it begin with 01 ?
How should I do to keep the order of my collection ?
Upvotes: 1
Views: 956
Reputation: 350725
That is how properties are ordered in EcmaScript1: when the property name is the canonical string- representation of an array index value (i.e., decimal digits, up to 232-1, and without padded zeroes), then these are sorted in numerical order before any other properties.
Note that this is not related to lodash, but to EcmaScript itself.
To enforce an order you should not make your result a plain object, but an array with pairs, where the first value in the pair is the (numeric) property, and the second is the actual value (object array in your case).
In plain JS you can create that pair-based structure with:
let map = new Map(conso.map(o => [o.date, []]));
conso.forEach(o => map.get(o.date).push(o));
let result = [...map];
If you really need the plain object format, then you could consider prefixing the properties with some non-digit character.
1There are a lot of nuances to the "order" of object properties. See Does ES6 introduce a well-defined order of enumeration for object properties? for a more elaborate explanation
Upvotes: 2
Reputation: 668
object in js isn't sorted, it means that after adding an element (key + value) to the object it position will be defined by a random function on its key (it changes from one prog-lang to another)
other possible solution is using array of arrays. which the main array will represent the whole groups and each subarray will represent a specific group.
we can acheive it by a simple sort on top of the current results.
var conso = [{ date: '25', value: '1410' },
{ date: '25', value: '1132' },
{ date: '26', value: '1482' },
{ date: '26', value: '3546' },
{ date: '27', value: '3748' },
{ date: '27', value: '3482' },
{ date: '28', value: '3164' },
{ date: '28', value: '2626' },
{ date: '29', value: '1110' },
{ date: '29', value: '948' },
{ date: '01', value: '1260' },
{ date: '01', value: '1228' },
{ date: '02', value: '1120' },
{ date: '02', value: '1056' },
{ date: '03', value: '1214' },
{ date: '04', value: '1100' },
{ date: '05', value: '1624' },
{ date: '06', value: '1544' },
{ date: '07', value: '1846' },
{ date: '08', value: '1370' },
{ date: '09', value: '1262' },
{ date: '10', value: '542' },
{ date: '10', value: '492' },];
let groups = _.groupBy(conso, 'date');
/// create an array of the original sorting dates
let sorting = _.map(conso, 'date')
// sort the group values (arrays) by their first element's date
// compare its value to the original solution date.
let finalSolution = _.sortBy(
Object.values(groups),
(k) => sorting.indexOf(k[0].date)
)
you can read more about js object key sorting here
Upvotes: 0