在JSON对象数组中搜索最大值

时间:2017-03-28 22:26:18

标签: javascript json underscore.js

我有一个JSON对象数组,如下所示:

    [ { _id: 58d98fc46cb2342d6848ae3,
    updateNumber: '1',
    resolution: 'tbd',
    nextUpdate: Mon Mar 27 2017 17:06:00 GMT-0400 (EDT),
    update: 'update 1',
    subject: 'test1',
    impact: 'test1',
    incidentNumber: '12345',
    wasNew: true,
    __v: 0 },
  { _id: 58d880126fb5087d684c8de4,
    updateNumber: '2',
    resolution: 'tbd',
    nextUpdate: Mon Mar 27 2017 18:06:00 GMT-0400 (EDT),
    update: 'update 2',
    subject: 'test1',
    impact: 'test1',
    incidentNumber: '12345',
    wasNew: true,
    __v: 0 },
  { _id: 58c23ae21bt2743d6328ae3,
    updateNumber: '1',
    resolution: 'tbd',
    nextUpdate: Mon Mar 27 2017 17:06:00 GMT-0400 (EDT),
    update: 'update 1',
    subject: 'test2',
    impact: 'test2',
    incidentNumber: '23456',
    wasNew: true,
    __v: 0 } ]

我需要做的是针对每个事件编号,获取最新更新。每个incidentNumber都有多个更新,我希望能够检索最新的更新(在上面的示例中,对于incidentNumber 12345更新2,为incidentNumber 23456更新1)

到目前为止,我已经尝试了_.max的变体,它只适用于一个incidentNumber而不是多个。

我进行了广泛的搜索,到目前为止还没有发现任何涉及我所拥有的相同数据集的问题。

有人能指出我如何开始解决这个问题吗?

由于

3 个答案:

答案 0 :(得分:2)

您可以先选择包含所需incidentNumber的项目,然后从中获取最大updateNumber的项目。 在es6语法中,假设您的数据位于data变量

中,它将看起来像这样
data
 .filter(d => d.incidentNumber === '12345')
 .reduce((o, e) => o.updateNumber && o.updateNumber > e.updateNumber ? o : e, {})

在es5语法中,它有点冗长

data
  .filter(function(d) { return d.incidentNumber === '12345'; })
  .reduce(function(o, e) { return  o.updateNumber && o.updateNumber > e.updateNumber ? o : e}, {})

或者你可以进行过滤并在一次通过中获得最大值

data.reduce(function(o, e) { return (e.incidentNumber === '12345' &&  o.updateNumber && o.updateNumber > e.updateNumber) ? o : e}, {})

要获取具有每个唯一事件编号的max updateNumber的对象,您可以在减少时维护由事件编号索引的对象哈希

var results = data.reduce(function (m, e) {
    if (e.updateNumber && (!m[e.incidentNumber] || m[e.incidentNumber].updateNumber < e.updateNumber)) {
        m[e.incidentNumber] = e;
    }
    return m;
}, {});

Object.values(results); // will contain the array of objects with max updateNumber

答案 1 :(得分:0)

要获取所有事件最新更新,您可以执行以下操作:

  • arr 是您的一系列事件
  • id 是您的标识符
  • 计数器是您比较
  • 的值
function getLatestUpdate(arr, id, counter) {
  var _latest = [];
  var latest = [];

  while (arr.length) {
    var item = arr.shift();
    var currentUpdate = _latest[item[id]];

    _latest[item[id]] = (!currentUpdate) ? item : (currentUpdate[counter] > item[counter] ? currentUpdate : item);
  }

  for(key in _latest) {
    latest.push(_latest[key]);
  }

  return latest;
}

var latest = getLatestUpdate(arr, '_id', 'updateNumber');

如果可能效率最高,但它利用数组作为对象并在过滤数组时比较对象计数器的值,然后在完成时将对象存在并推送到数据库中存储在那里的键/值对。

答案 2 :(得分:0)

最简单(最快,没有破坏性)的方法是使用地图对象,如下所示:

function getLatest(arr) {
  map = {};
    arr.forEach(item => {
    var i = item.incidentNumber;
    if (!map[i] || map[i].updateNumber<item.updateNumber) {
        map[i] = item;
    }
  })
  return Object.keys(map).map(key => map[key])
}