JavaScript 按 2 个值对数组排序
JavaScript sort array by 2 values
我有一个数组,我想按 "id" 和 "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"}
]
应该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"}
]
您可以使用 .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);
输出:
[ { 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' } ]
Array.sort 采用带有两个参数的函数来比较数组的两个元素。如果此函数 returns 为负数,则 a 位于 b 之前,如果为 returns 正数,则 a 位于 b 之前,如果为 returns 0,则它们保持原样。在这里,我按 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;
}
});
试一试
var sorted = unsorted.sort(function(a, b) {
return a.id === b.id ?
Date.parse(a.date) - Date.parse(b.date) :
a.id - b.id ;
});
说明
如果id
字段相等,我们要return比较date
字段
如果id
字段不相等,我们将return比较id
字段
这是一个使用 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]);
}
结果为:
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"}
分而治之!
首先将输入数组缩减为 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;
}, {});
现在您可以通过遍历对象的键对每个数组进行排序,请注意这会修改 dataById 映射。
Object.keys(dataById).forEach(function (id) {
dataById[id] = dataById[id].sort();
});
最后,您可以再次通过遍历映射中的键将所有数据组合在一起。请注意 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]);
}, []);
这不是解决问题的最有效方法,但希望它能对您的思考过程有所帮助。
我有一个数组,我想按 "id" 和 "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"}
]
应该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"}
]
您可以使用 .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);
输出:
[ { 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' } ]
Array.sort 采用带有两个参数的函数来比较数组的两个元素。如果此函数 returns 为负数,则 a 位于 b 之前,如果为 returns 正数,则 a 位于 b 之前,如果为 returns 0,则它们保持原样。在这里,我按 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;
}
});
试一试
var sorted = unsorted.sort(function(a, b) {
return a.id === b.id ?
Date.parse(a.date) - Date.parse(b.date) :
a.id - b.id ;
});
说明
如果id
字段相等,我们要return比较date
字段
如果id
字段不相等,我们将return比较id
字段
这是一个使用 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]);
}
结果为:
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"}
分而治之!
首先将输入数组缩减为 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;
}, {});
现在您可以通过遍历对象的键对每个数组进行排序,请注意这会修改 dataById 映射。
Object.keys(dataById).forEach(function (id) {
dataById[id] = dataById[id].sort();
});
最后,您可以再次通过遍历映射中的键将所有数据组合在一起。请注意 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]);
}, []);
这不是解决问题的最有效方法,但希望它能对您的思考过程有所帮助。