javascript - 如何对对象数组中的多个属性值进行计数和分组?

标签 javascript arrays object

我有一个对象数组:

[
  {'year': 2019, 'a_academic': 3, 'f_security': 4, ..., 'k_services': 3},
  {'year': 2019, 'a_academic': 2, 'f_security': 2, ..., 'k_services': 4},
  {'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 1},
  ...
  {'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 3},
]

如何计算多个属性值,然后将其分组,并将其保存在新对象中,例如:

{
  'a_academic': {
      4: 0,
      3: 3,
      2: 1,
      1: 0
  },
  'f_security': {
      4: 1,
      3: 2,
      2: 1,
      1: 0
  },
  ...,
  'k_services': {
      4: 1,
      3: 2,
      2: 0,
      1: 1
  }
}

我可以使用reduce 并手动访问 key 来完成此操作,但仅限一个属性:

let count = array.reduce((res, cur) => {
    res[cur.a_academic] = res[cur.a_academic] ? res[cur.a_academic] + 1 : 1;
    return res;
  }, {});

console.log(count);

结果:

{
  3: 3,
  2: 1
}

如何有效地实现这一点,以便它适用于所有其他属性,而无需手动访问它?

最佳答案

您可以定义一个要计数的键数组,然后在 Object.entries 上使用带有嵌套 forEach 循环的 reduce 方法,计算每个定义的键出现的值。

const data = [
  {'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3},
  {'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4},
  {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1},
  {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3},
]

const props = ['a_academic', 'f_security', 'k_services']

const result = data.reduce((r, e) => {
  Object.entries(e).forEach(([k, v]) => {
    if (props.includes(k)) {
      if (!r[k]) r[k] = {}
      r[k][v] = (r[k][v] || 0) + 1
    }
  })
  return r;
}, {})

console.log(result)

要在每个对象中填充空值,您必须首先找到整个数据的最小值和最大值,而且还要找到定义的 Prop 的最小值和最大值。

const data = [
  {'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3},
  {'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4},
  {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1},
  {'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3},
]

const props = ['a_academic', 'f_security', 'k_services']

const values = data.map(e => {
  return Object.entries(e)
    .filter(([k]) => props.includes(k))
    .map(([k, v]) => v)
}).flat()

const max = Math.max(...values)
const min = Math.min(...values)

const result = data.reduce((r, e) => {
  Object.entries(e).forEach(([k, v]) => {
    if (props.includes(k)) {
      if (!r[k]) {
        r[k] = {}

        for (let i = min; i <= max; i++) {
          r[k][i] = 0
        }
      }

      r[k][v] += 1
    }
  })
  return r;
}, {})


console.log(result)

关于javascript - 如何对对象数组中的多个属性值进行计数和分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60474369/

相关文章:

javascript - 如何舍入对象内的数字

c# - 如何为数组中的对象创建事件?

javascript - JS 中是否有相当于 Python 的 .get() 的功能?

javascript - 如何强制将 Shiny 的输入大写

javascript - XMLHttpRequest - flickr - 跨源 header

javascript - 处理网页上的所有/任何链接点击

Java - "invalid stream header"ArrayList 的序列化

java - 声明包含整数数组的对象的构造函数

multithreading - 为什么 scala 在计算 Future 中的按名称参数时会挂起?

javascript - 在数组对象中查找一个值并使用该对象中的另一个值