首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从对象数组中提取最小/最大值,而不知道属性名称

从对象数组中提取最小/最大值,而不知道属性名称
EN

Stack Overflow用户
提问于 2018-08-31 05:12:49
回答 2查看 64关注 0票数 0

我想从集合的所有属性中提取最小和最大值:

代码语言:javascript
复制
"data": [
    {
        "food": 41000,
        "drinks": 60,
        "toys": 18961,
        "candy": 8740
    },
    {
        "food": 245,
        "abusive-usage": 96,
        "drinks": 5971,
        "candy": 12492,
        "somethingnew": 8
    },
    {
        "food": 365,
        "abusive-usage": 84,
        "toys": 22605,
        "candy": 9256,
        "somethingold": 1
    },
    {}
];

如果我事先知道属性名称,我可以这样做:

代码语言:javascript
复制
const max = Math.max(...graph.datasets.urgency.map((x) => x.knownPropertyName));

不幸的是,正如我试图用上面的例子演示的那样,属性是动态的。我事先不知道那里会有什么属性名称,实际上我也不关心;我只需要值的最小值和最大值。可以安全地假设所有的值都是数字。

通过下面的代码片段,我可以让它正常工作:

代码语言:javascript
复制
    let maxUrgency = 0;
    let minUrgency = 0;
    data.forEach((day) => {
        Object.keys(day).forEach((key, index) => {
            if (day[key] > maxUrgency) maxUrgency = day[key];
            if (day[key] < minUrgency) minUrgency = day[key];
        });
    });

尽管它可以工作,但在这里简单地使用for/forEach似乎过于繁琐-而且可能不是最有效的。相反,我正在寻找一种更干净、更普通的方法(ES6首选)来实现这一点。例如,一个整洁的基于Array.prototype的lambda构造。最好,我不想使用lib,比如lodash或underscore。

如何改进这段代码,理想情况下,我不必遍历集合中每个项目的每个属性?

相关的问题,但绝对不是一样的:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-31 05:17:44

如果你不介意做一些ES2017,这里有Object.values()。它与array.reduce()一起使用。

代码语言:javascript
复制
const data = [{
    "food": 41000,
    "drinks": 60,
    "toys": 18961,
    "candy": 8740
  },
  {
    "food": 245,
    "abusive-usage": 96,
    "drinks": 5971,
    "candy": 12492,
    "somethingnew": 8
  },
  {
    "food": 365,
    "abusive-usage": 84,
    "toys": 22605,
    "candy": 9256,
    "somethingold": 1
  },
  {}
]

const values = data.reduce((c, v) => [...c, ...Object.values(v)], [])
const min = Math.min(...values)
const max = Math.max(...values)

console.log(min, max)

或者,可以将array.map()array.concat()一起使用,而不是array.reduce()

代码语言:javascript
复制
const data = [{
    "food": 41000,
    "drinks": 60,
    "toys": 18961,
    "candy": 8740
  },
  {
    "food": 245,
    "abusive-usage": 96,
    "drinks": 5971,
    "candy": 12492,
    "somethingnew": 8
  },
  {
    "food": 365,
    "abusive-usage": 84,
    "toys": 22605,
    "candy": 9256,
    "somethingold": 1
  },
  {}
]

const valueArrays = data.map(v => Object.values(v))
const values = Array.prototype.concat.call(...valueArrays)
const min = Math.min(...values)
const max = Math.max(...values)

console.log(min, max)

票数 1
EN

Stack Overflow用户

发布于 2018-08-31 05:42:05

使用reduce()for in循环的示例

代码语言:javascript
复制
var obj = {
    "data": [
        {
            "food": 41000,
            "drinks": 60,
            "toys": 18961,
            "candy": 8740
        },
        {
            "food": 245,
            "abusive-usage": 96,
            "drinks": 5971,
            "candy": 12492,
            "somethingnew": 8
        },
        {
            "food": 365,
            "abusive-usage": 84,
            "toys": 22605,
            "candy": 9256,
            "somethingold": 1
        }
    ]
};

//max of each property

var res = obj.data.reduce((acc, c) => {

    for (let p in c) {
        if (c[p] > (acc[p] || 0)) acc[p] = c[p];
    }

    return acc;

}, {})

console.log(res)

//absolute max and min

var res = obj.data.reduce((acc, c) => {

    for (let p in c) {
        if (c[p] > acc[1] ) acc[1] = c[p];
        if (c[p] < acc[0] ) acc[0] = c[p];
    }
return acc
}, [Infinity,0])


console.log(res)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52105436

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档