如何使用第二个数组中对象的相关 属性 对对象数组进行排序
how to sort an array of objects using a related property from objects in second array
有很多关于 JavaScript 排序的问题,但我没有找到任何解决这个问题的东西,所以我不认为这是重复的。
我正在从 api:
中获取这样的数据
//items array
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: mary}, {id:4, name:'jane'}]
//sort order array
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}]
如何根据顺序数组中对象的 sortindex
属性 对项目数组进行排序?两个数组中的对象有共同的属性id
。有没有优雅的lodash/underscore解决方案?
如果您将订单存储为地图,使用香草 Javascript 是相当简单的。
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = {1:4, 2:2, 3:1, 4:3};
items.sort(function (a, b) {
return (order[a.id] > order[b.id]) - (order[a.id] < order[b.id]);
});
或者,如果您坚持使用原始数据,假设它已经按您显示的那样排序:
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
items.sort(function (a, b) {
var ai = order[a.id - 1].sortindex;
var bi = order[b.id - 1].sortindex;
return (ai > bi) - (ai < bi);
});
如果您不能假定数据已排序,请参阅this question, for example了解如何从您的数据创建地图。
lodash 很简单。 sortBy
函数会将item移动到sortindex
位置,所以我们只需要用find
得到对应的对象,return其sortindex
属性 供 sortBy
使用。
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
var sorted = _.sortBy(items, function(item) {
// sorts by the value returned here
return _.find(order, function(ordItem) {
// find the object where the id's match
return item.id === ordItem.id;
}).sortindex; // that object's sortindex property is returned
});
document.body.textContent = JSON.stringify(sorted);
<script src="https://rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
见演示:http://jsbin.com/qaquzi/1/edit?js,console
//items array
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}]
//sort order array
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}]
var sortedOrder = _.sortBy(order, 'sortindex');
var bb = _.map(sortedOrder, function (i) {
return i.id;
})
var sorted = [];
for (var i = 0, ii = bb.length; i < ii; i++) {
for (var m = 0, mm = items.length; m < mm; m++) {
var a = items[m];
if (a.id == bb[i]) {
sorted.push(items[m]);
}
}
}
console.log(sorted);
这是我的解决方案:
var items = [
{ id: 1, name: 'bill' },
{ id: 2, name: 'sam' },
{ id: 3, name: 'mary' },
{ id: 4, name: 'jane' }
];
var order = [
{ id: 1, sortindex: 4 },
{ id: 2, sortindex: 2 },
{ id: 3, sortindex: 1 },
{ id: 4, sortindex: 3 }
];
_(items)
.indexBy('id')
.at(_.pluck(_.sortBy(order, 'sortindex'), 'id'))
.pluck('name')
.value();
// → [ 'mary', 'sam', 'jane', 'bill' ]
这是正在发生的事情:
这是我的 solution。如果您知道两个数组的长度和 ID 的位置都匹配,那么这是一个简洁的解决方案:
_.chain(items)
.merge(order)
.sortBy('sortindex')
.map(_.partialRight(_.omit, 'sortindex'))
.value()
否则,如果它们不能保证被排序,那么这些项目可以用 map/find/merge 来解决。
_.chain(items)
.map(function(item) {
return _.merge(item, _.find(order, {'id': item.id}));
})
.sortBy('sortindex')
.map(_.partialRight(_.omit, 'sortindex'))
.value()
有很多关于 JavaScript 排序的问题,但我没有找到任何解决这个问题的东西,所以我不认为这是重复的。
我正在从 api:
中获取这样的数据//items array
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: mary}, {id:4, name:'jane'}]
//sort order array
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}]
如何根据顺序数组中对象的 sortindex
属性 对项目数组进行排序?两个数组中的对象有共同的属性id
。有没有优雅的lodash/underscore解决方案?
如果您将订单存储为地图,使用香草 Javascript 是相当简单的。
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = {1:4, 2:2, 3:1, 4:3};
items.sort(function (a, b) {
return (order[a.id] > order[b.id]) - (order[a.id] < order[b.id]);
});
或者,如果您坚持使用原始数据,假设它已经按您显示的那样排序:
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
items.sort(function (a, b) {
var ai = order[a.id - 1].sortindex;
var bi = order[b.id - 1].sortindex;
return (ai > bi) - (ai < bi);
});
如果您不能假定数据已排序,请参阅this question, for example了解如何从您的数据创建地图。
lodash 很简单。 sortBy
函数会将item移动到sortindex
位置,所以我们只需要用find
得到对应的对象,return其sortindex
属性 供 sortBy
使用。
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}];
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}];
var sorted = _.sortBy(items, function(item) {
// sorts by the value returned here
return _.find(order, function(ordItem) {
// find the object where the id's match
return item.id === ordItem.id;
}).sortindex; // that object's sortindex property is returned
});
document.body.textContent = JSON.stringify(sorted);
<script src="https://rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
见演示:http://jsbin.com/qaquzi/1/edit?js,console
//items array
var items = [{id:1, name:'bill'}, {id:2, name:'sam'}, {id:3, name: 'mary'}, {id:4, name:'jane'}]
//sort order array
var order = [{id:1, sortindex:4}, {id:2, sortindex:2}, {id:3, sortindex: 1}, {id:4, sortindex:3}]
var sortedOrder = _.sortBy(order, 'sortindex');
var bb = _.map(sortedOrder, function (i) {
return i.id;
})
var sorted = [];
for (var i = 0, ii = bb.length; i < ii; i++) {
for (var m = 0, mm = items.length; m < mm; m++) {
var a = items[m];
if (a.id == bb[i]) {
sorted.push(items[m]);
}
}
}
console.log(sorted);
这是我的解决方案:
var items = [
{ id: 1, name: 'bill' },
{ id: 2, name: 'sam' },
{ id: 3, name: 'mary' },
{ id: 4, name: 'jane' }
];
var order = [
{ id: 1, sortindex: 4 },
{ id: 2, sortindex: 2 },
{ id: 3, sortindex: 1 },
{ id: 4, sortindex: 3 }
];
_(items)
.indexBy('id')
.at(_.pluck(_.sortBy(order, 'sortindex'), 'id'))
.pluck('name')
.value();
// → [ 'mary', 'sam', 'jane', 'bill' ]
这是正在发生的事情:
这是我的 solution。如果您知道两个数组的长度和 ID 的位置都匹配,那么这是一个简洁的解决方案:
_.chain(items)
.merge(order)
.sortBy('sortindex')
.map(_.partialRight(_.omit, 'sortindex'))
.value()
否则,如果它们不能保证被排序,那么这些项目可以用 map/find/merge 来解决。
_.chain(items)
.map(function(item) {
return _.merge(item, _.find(order, {'id': item.id}));
})
.sortBy('sortindex')
.map(_.partialRight(_.omit, 'sortindex'))
.value()