获取基于另一个键排序的属性的最大/最小值

时间:2016-08-11 04:14:03

标签: arrays node.js object lodash

假设我有一个json对象数组,如:

[{ customerId:1, orderId:1-1, orderAmount:100
   customerId:2, orderId:2-1, orderAmount: 125
   customerId:1, orderId: 1-2, orderAmount: 112
  ............
}]

我希望找到每个客户的最高(或最低)订单,如

[{customerId:1, orderId:1-2, orderAmount:112},{.....}]

是否可以使用任何语言构造(我使用Node.js)或lodash。我认为可以按照customerId排序或按orderAmount排序在lodash中是直截了当但不是上面的组合

我能想到的另一种方法是双重forEachOf(异步)循环,这可能效率不高

感谢任何帮助......

2 个答案:

答案 0 :(得分:0)

_.sortBy允许您指定要排序的字段数组。您可以使用:

var output = _.sortBy(input, ['customerId', 'orderAmount']);

如果您还想将对象分组到数组中,以便更容易找到max&每个customerId的分钟数,您可以使用_.groupBy然后排序。

var output = _.mapValues(_.groupBy(input, 'customerId'), function(val) {
  return _.sortBy(val, 'orderAmount');
});

这将产生如下结构:

{
  "1": [
    { customerId: 1, orderId: "1-2", orderAmount: 112 },
    { customerId: 1, orderId: "1-1", orderAmount: 100 }
  ],
  "2": [
    { customerId: 2, orderId: "2-1", orderAmount: 125 }
  ]
}

答案 1 :(得分:0)

使用orderByorder升序或降序来决定是最低还是最高。按custormerId分组,并从每个客户订单中获取第一项:

function getMinMax(orders, min) { // orders - array of orders, min - true if minimum, undefined / false if maximum
  var order = !!min ? 'asc' : 'desc'; 
  
  return _(orders)
  .orderBy('orderAmount', order) // orderBy the orderAmount property, with order determining highest or lowest
  .groupBy('customerId') // group all orders by customer id
  .map(function(orders) { // create a new array of just the 1st order of each customer, which will be the highest or the lowest
    return orders[0];
  }).value();
}

var orders = [{
  customerId: 1,
  orderId: '1-1',
  orderAmount: 100
}, {
  customerId: 2,
  orderId: '1-2',
  orderAmount: 128
}, {
  customerId: 2,
  orderId: '1-3',
  orderAmount: 12
}, {
  customerId: 1,
  orderId: '1-3',
  orderAmount: 113
}, {
  customerId: 2,
  orderId: '1-1',
  orderAmount: 125
}, {
  customerId: 2,
  orderId: '4-1',
  orderAmount: 11
}, {
  customerId: 1,
  orderId: '1-2',
  orderAmount: 25
}];

var highestOrders = getMinMax(orders); 

console.log('highestOrders', highestOrders);

var lowesetOrders = getMinMax(orders, true); 

console.log('lowesetOrders', lowesetOrders);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.2/lodash.min.js"></script>