Javascript 如何动态地将对象数组聚合到组中

Javascript 如何动态地将对象数组聚合到组中,javascript,reactjs,Javascript,Reactjs,我有一些动态数据。假设id始终存在,而另一个键:value将更改 我试图用一种抽象的方法来概括我的想法,但我认为我对现有的工具了解得不够 我正在寻找一种动态聚合的方法 例如,如果我有以下数据: const dataum=[{ “id”:1, “q1”:“是”, “q2”:4, “q3”:空 }, { “id”:2, “q1”:空, “q2”:14, “q3”:“中等” }, { “id”:3, “q1”:“否”, “q2”:83, “第三季度”:“高” }, { “id”:27, “q1”:“是

我有一些动态数据。假设id始终存在,而另一个键:value将更改

我试图用一种抽象的方法来概括我的想法,但我认为我对现有的工具了解得不够

我正在寻找一种动态聚合的方法

例如,如果我有以下数据:

const dataum=[{
“id”:1,
“q1”:“是”,
“q2”:4,
“q3”:空
}, {
“id”:2,
“q1”:空,
“q2”:14,
“q3”:“中等”
}, {
“id”:3,
“q1”:“否”,
“q2”:83,
“第三季度”:“高”
}, {
“id”:27,
“q1”:“是”,
“q2”:62,
“q3”:空
}]
我正试图创造这样的东西:

const aggData=[{
“q1”:{
“是”:2,
“空”:1,
“否”:1
}
}, {
“q2”:{
“0到60”:2,
“60到70”:1,
“70到100”:1,
“空”:0
}
} {
“q3”:{
“中等”:1,
“空”:2,
“高”:1
}
}]
我没怎么试过。因为我被最外层的进程/功能卡住了。我考虑过()键和.values,我看了
array.reduce()
。。。但我仍然不知道如何动态地说:
newObject.key.someAnswer+=1
其中键是动态的,而答案是动态的(或null)

我不会太担心射程。。。我想只要有一点点帮助,我就能完成这个过程

我可以以任何格式为该流程提供更多数据,如:

const qproperty=[{
“q1”:{
“类型”:“YN”,
“值”:[“是”、“否”]
}
}, {
“q3”:{
“类型”:“LMH”,
“值”:[“低”、“中”、“高”]
}
}]

如果这有助于减少代码占用,请将其抽象化。

尽管您的输入数据与预期的输出数据并不匹配(这可能是您获得否决票的原因),但我认为您需要这样的内容:

const dataum = [
  { id: 1, q1: "yes", q2: 4, q3: null },
  { id: 2, q1: null, q2: 14, q3: "medium" },
  { id: 3, q1: "no", q2: 83, q3: "high" },
  { id: 27, q1: "yes", q2: 62, q3: null },
];
const intermediate1 = dataum.reduce((acc, curr) => {
  Object.entries(curr).forEach(([k,v]) => {
    if (k !== "id") {
      if (!acc[k]) {
        acc[k] = [];
      }
      acc[k].push(v);
    }
  });
  return acc;
}, {});

console.log(intermediate1);
// {
//   q1: [ 'yes', null, 'no', 'yes' ],
//   q2: [ 4, 14, 83, 62 ],
//   q3: [ null, 'medium', 'high', null ]
// }

const final = Object.entries(intermediate1).reduce((acc, [k, v]) => {
  const accumulated = v.reduce((inner_acc, inner_val) => {
    if (inner_val === null) {
      inner_val = "empty";
    }
    if (!inner_acc[inner_val]) {
      inner_acc[inner_val] = 0;
    }
    inner_acc[inner_val] += 1;
    return inner_acc;
  }, {});    
  acc.push({
    [k]: accumulated,
  });
  return acc;
}, []);

console.log(final);      
// [
//   { q1: { yes: 2, empty: 1, no: 1 } },
//   { q2: { '4': 1, '14': 1, '62': 1, '83': 1 } },
//   { q3: { empty: 2, medium: 1, high: 1 } }
// ]

你可能想看看lodash,也许他们已经有类似的东西了。

如果你不担心实现的话,你可以使用
lodash.groupby


这太优雅了,谢谢你!我见过洛达斯出现过好几次。不知道它是做什么的,只是在某些情况下人们会说“使用lodash”。喜欢约会的时刻。。。lodash做什么?请查看文档()以获得详细解释和良好示例。Lodash(下划线的后继者)是一个库,用于排序/过滤/映射/分组/压缩/减少/装箱/查找/取消装箱/检查/排序常见用例的数据。我喜欢使用Lodash,但依我看,这并不是OP想要的。对于每个qN,他希望有一个对象,而你有一个对象数组。此外,OP希望将
null
替换为“empty”。我还了解到,按键(
q1
q2
,…)事先不知道。还有,你的
q3
null/empty:2
在哪里?@Joel-yeah足够公平,只是一个例子,可以很容易地调整-OP中的例子有点混乱。不管怎样,在答案上做得很好!谢谢@neeko对象数组也适用于我。将(Object.values/keys)映射到图表列表中。看来我需要在洛达斯身上好好读书了。
const groupBy = require('lodash.groupby');

const keys = ["q1", "q2", "q2"];
const dataum = [
  { id: 1, q1: "yes", q2: 4, q3: null },
  { id: 2, q1: null, q2: 14, q3: "medium" },
  { id: 3, q1: "no", q2: 83, q3: "high" },
  { id: 27, q1: "yes", q2: 62, q3: null }
];

const grouped = [];

function countKeys(object) {
  const counts = [];
  const keys = Object.keys(object);

  keys.forEach((key) => {
    const count = Object.values(object[key]).length;
    counts.push({ [key]: count });
  });

  return counts;
}

keys.forEach((key) => {
  const groups = _.groupBy(dataum, key);
  const counts = countKeys(groups);
  const groupedRow = { [key]: counts };
  grouped.push(groupedRow);
});

console.log(grouped);

// const output = [
//   { q1: [{ yes: 2 }, { null: 1 }, { no: 1 }] },
//   { q2: [{ "4": 1 }, { "14": 1 }, { "62": 1 }, { "83": 1 }] },
//   { q2: [{ "4": 1 }, { "14": 1 }, { "62": 1 }, { "83": 1 }] }
// ];