Reputation: 834
I've an array and I want to sort it by "id" and "date" from smaller to bigger. How can I do this correctly ?
Example :
var unsorted = [
{id: 1, date: "2015-01-18T15:00:00+01:00"},
{id: 1, date: "2015-01-18T14:30:00+01:00"},
{id: 2, date: "2015-01-18T10:00:00+01:00"},
{id: 1, date: "2015-01-18T16:00:00+01:00"},
{id: 3, date: "2015-01-18T14:15:00+01:00"},
{id: 2, date: "2015-01-18T14:00:00+01:00"}
]
Should return :
var sorted = [
{id: 1, date: "2015-01-18T14:30:00+01:00"},
{id: 1, date: "2015-01-18T15:00:00+01:00"},
{id: 1, date: "2015-01-18T16:00:00+01:00"},
{id: 2, date: "2015-01-18T10:00:00+01:00"},
{id: 2, date: "2015-01-18T14:00:00+01:00"},
{id: 3, date: "2015-01-18T14:15:00+01:00"}
]
Upvotes: 3
Views: 575
Reputation: 6209
Divide and conquer!
Start by reducing the input array into a map of id => object, ie:
var dataById = unsorted.reduce(function (soFar, value) {
// Initialise the array if we haven't processed this
// id yet.
if (soFar[value.id] === undefined) {
soFar[value.id] = [];
}
// ad this object to Array.
soFar[value.id].push(value);
return soFar;
}, {});
Now you can sort each array by looping over the Object's keys, note this modifies the dataById map in place.
Object.keys(dataById).forEach(function (id) {
dataById[id] = dataById[id].sort();
});
Finally, you can combine all the data together, again by iterating over the keys in the map. Note that maps (objects) in javascript don't guarantee the order of their keys, so you may wish to dump the ids out to an Array first before iterating:
var ids = Object.keys(dataById).sort();
// Reduce the ids into an Array of data.
var ids.reduce(function (soFar, value) {
return soFar.concat(dataById[id]);
}, []);
Not the most efficient way of solving your problem, but hopefully it gives you some help with the thought process.
Upvotes: 0
Reputation: 18861
Here is an example using array.sort:
var arr = [
{id: 1, date: "2015-01-18T15:00:00+01:00"},
{id: 1, date: "2015-01-18T14:30:00+01:00"},
{id: 2, date: "2015-01-18T10:00:00+01:00"},
{id: 1, date: "2015-01-18T16:00:00+01:00"},
{id: 3, date: "2015-01-18T14:15:00+01:00"},
{id: 2, date: "2015-01-18T14:00:00+01:00"}
];
arr.sort(function(a,b){
if (a.id == b.id) return a.date.localeCompare(b.date);
return a.id-b.id;
});
// test
for (var i in arr) {
console.log(arr[i]);
}
Result being:
Object {id: 1, date: "2015-01-18T14:30:00+01:00"}
Object {id: 1, date: "2015-01-18T15:00:00+01:00"}
Object {id: 1, date: "2015-01-18T16:00:00+01:00"}
Object {id: 2, date: "2015-01-18T10:00:00+01:00"}
Object {id: 2, date: "2015-01-18T14:00:00+01:00"}
Object {id: 3, date: "2015-01-18T14:15:00+01:00"}
Upvotes: 7
Reputation: 135247
Give this a shot
var sorted = unsorted.sort(function(a, b) {
return a.id === b.id ?
Date.parse(a.date) - Date.parse(b.date) :
a.id - b.id ;
});
Explanation
If the id
field is equal, we want to return the comparison of the date
field.
If the id
field is not equal, we will return the comparison of the id
field
Upvotes: 3
Reputation: 16718
You can use .sort()
:
var unsorted = [
{id: 1, date: "2015-01-18T15:00:00+01:00"},
{id: 1, date: "2015-01-18T14:30:00+01:00"},
{id: 2, date: "2015-01-18T10:00:00+01:00"},
{id: 1, date: "2015-01-18T16:00:00+01:00"},
{id: 3, date: "2015-01-18T14:15:00+01:00"},
{id: 2, date: "2015-01-18T14:00:00+01:00"}
];
var sorted = unsorted.sort(function(a, b) {
return a.id == b.id ?
new Date(a.date) - new Date(b.date) : a.id - b.id;
});
console.log(sorted);
Output:
[ { id: 1, date: '2015-01-18T14:30:00+01:00' },
{ id: 1, date: '2015-01-18T15:00:00+01:00' },
{ id: 1, date: '2015-01-18T16:00:00+01:00' },
{ id: 2, date: '2015-01-18T10:00:00+01:00' },
{ id: 2, date: '2015-01-18T14:00:00+01:00' },
{ id: 3, date: '2015-01-18T14:15:00+01:00' } ]
Upvotes: 5
Reputation: 3739
Array.sort takes a function with two parameters to compare two elements of an array. If this function returns a negative then a is placed before b, if it returns positive then a is placed before b and if it returns 0 they stay as they are. Here I compare them by id and if their IDs are same then I compare them by date.
var unsorted = [{
id: 1,
date: "2015-01-18T15:00:00+01:00"
}, {
id: 1,
date: "2015-01-18T14:30:00+01:00"
}, {
id: 2,
date: "2015-01-18T10:00:00+01:00"
}, {
id: 1,
date: "2015-01-18T16:00:00+01:00"
}, {
id: 3,
date: "2015-01-18T14:15:00+01:00"
}, {
id: 2,
date: "2015-01-18T14:00:00+01:00"
}];
unsorted.sort(function(a, b) {
if (a.id < b.id)
return -1;
else if (a.id > b.id)
return 1;
else {
if (a.date < b.date)
return -1;
else if (a.date > b.date)
return 1;
else
return 0;
}
});
Upvotes: 0