简体   繁体   English

JavaScript排序数组由2个值组成

[英]JavaScript sort array by 2 values

I've an array and I want to sort it by "id" and "date" from smaller to bigger. 我有一个数组,我想按“id”和“date”从小到大排序。 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"} 
]

Here is an example using array.sort: 以下是使用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() : 你可以使用.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 comparison of the date field. 如果id字段相等,我们想要返回date字段的比较。

If the id field is not equal, we will return the comparison of the id field 如果id字段不相等,我们将返回id字段的比较

Array.sort takes a function with two parameters to compare two elements of an array. Array.sort采用带有两个参数的函数来比较数组的两个元素。 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. 如果此函数返回负数,则a放在b之前,如果它返回正数,则a放在b之前,如果它返回0,则它们保持不变。 Here I compare them by id and if their IDs are same then I compare them by date. 在这里,我通过id比较它们,如果它们的ID相同,那么我按日期比较它们。

 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: 首先将输入数组缩减为id => object的映射,即:

 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. 现在,您可以通过循环对象的键对每个数组进行排序,请注意,这会修改dataById映射。

 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: 请注意,javascript中的地图(对象)不保证其键的顺序,因此您可能希望在迭代之前首先将ID转储到数组:

 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. 不是解决问题的最有效方法,但希望它能为您提供一些思考过程的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM