如何使用第二个数组中对象的相关属性对对象数组进行排序

时间:2015-03-05 00:17:49

标签: javascript underscore.js lodash

关于使用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属性对items数组进行排序?两个数组中的对象具有公共属性id。是否有优雅的lodash / undercore解决方案?

5 个答案:

答案 0 :(得分:2)

用lodash直截了当。 sortBy函数会将项目移动到sortindex位置,因此我们只需使用find获取相应的对象,并返回其sortindex属性{{1使用。



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);




答案 1 :(得分:0)

如果您将订单存储为地图,则可以使用vanilla 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有关如何根据数据创建地图的信息。

答案 2 :(得分:0)

参见演示: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);

答案 3 :(得分:0)

这是我的解决方案:

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

这是发生了什么:

  • indexBy()函数将items转换为对象,其中id值为关键字。
  • at()函数从传入的键中的对象按顺序获取值。
  • sortBy()功能按order键对sortindex进行排序。
  • pluck()函数获取已排序的id数组。

答案 4 :(得分:0)

这是我的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()