JS:按类别的最大值过滤对象数组 [英] JS: Filter array of objects by max value per category

查看:308
本文介绍了JS:按类别的最大值过滤对象数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是实现类似sql的过滤效果的最有效/最优雅的方法.我想过滤它们并仅获取那些在某些组中具有最大值的对象.

What is most efficient / elegant way to achieve sql-like filtering effect. I want to filter them and get only that objects which are max value in some group.

这是我的代码,它可以工作,但可能不是最好的方法:

This is my code, it works but probably it's not best way:

uniqueValues = (arr) => [...new Set(arr)];
getMaxTimeOf = (arr) => Math.max(...arr.map(o => o.timeStamp), 0);
selectorName = (name) => (obj) => obj.name === name;
selectorTime = (time) => (obj) => obj.timeStamp === time;
getGroup = (obj, selector) => obj.filter(selector)

onlyLastChangedFrom = (history) => {
const uniqueNames = uniqueValues(history.map(o => o.name))
let filtered = []
 uniqueNames.forEach(name => {
  const group = getGroup(history, selectorName(name))
  const groupLastTime = getMaxTimeOf(group)
  const lastChange = getGroup(group, selectorTime(groupLastTime))
  filtered.push(lastChange[0])
 });
 return filtered
}   
onlyLastChangedFrom(history)

    // Input:
    [ { name: 'bathroom',
        value: 54,
        timeStamp: 1562318089713 },
      { name: 'bathroom',
        value: 55,
        timeStamp: 1562318090807 },
      { name: 'bedroom',
        value: 48,
        timeStamp: 1562318092084 },
      { name: 'bedroom',
        value: 49,
        timeStamp: 1562318092223 },
      { name: 'room',
        value: 41,
        timeStamp: 1562318093467 } ]

    // Output:
    [ { name: 'bathroom',
        value: 55,
        timeStamp: 1562318090807 },
      { name: 'bedroom',
        value: 49,
        timeStamp: 1562318092223 },
      { name: 'room',
        value: 41,
        timeStamp: 1562318093467 } ]

推荐答案

使用name属性作为键将数组简化为对象.对于每个项目,检查累加器中存在的项目的值是否比当前项目高,如果没有,请用当前项目替换它.使用 Object.values() :

Reduce the array to an object, using the name property as the key. For each item, check if the item that exists in the accumulator has a higher value than the current item, and if not replace it with the current item. Convert back to an array with Object.values():

const arr = [{"name":"bathroom","value":54,"timeStamp":1562318089713},{"name":"bathroom","value":55,"timeStamp":1562318090807},{"name":"bedroom","value":48,"timeStamp":1562318092084},{"name":"bedroom","value":49,"timeStamp":1562318092223},{"name":"room","value":41,"timeStamp":1562318093467}]

const result = Object.values(arr.reduce((r, o) => {
  r[o.name] = r[o.name] && r[o.name].value > o.value ? r[o.name] : o

  return r
}, {}))

console.log(result)

这篇关于JS:按类别的最大值过滤对象数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆