admin管理员组

文章数量:1323715

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"} 
]

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"} 
]
Share Improve this question edited Jan 18, 2015 at 19:27 AstroCB 12.4k20 gold badges59 silver badges74 bronze badges asked Jan 18, 2015 at 19:26 robpalrobpal 8344 gold badges10 silver badges21 bronze badges 5
  • 1 ummmm why don't you sort the data using ORDER BY when you fetch it from the db on server? – MightyPork Commented Jan 18, 2015 at 19:27
  • hmm well array.sort() takes parator function as an argument, so try with that. – MightyPork Commented Jan 18, 2015 at 19:31
  • i've tried many variations and didn't find correct solution, so this why i'm asking here. – robpal Commented Jan 18, 2015 at 19:32
  • What you mean I can't do that – IGRACH Commented Jan 18, 2015 at 19:33
  • @IGRACH i can't handle data from server side, because i'm getting this data via pubnub and etc.. – robpal Commented Jan 18, 2015 at 19:57
Add a ment  | 

5 Answers 5

Reset to default 7

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"}

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' } ]

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 parison of the date field.

If the id field is not equal, we will return the parison of the id field

Array.sort takes a function with two parameters to pare 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 pare them by id and if their IDs are same then I pare 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;
  }
});

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 bine 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.

本文标签: JavaScript sort array by 2 valuesStack Overflow