JavaScript - 按键减少对象数组

14

处理一个类似于以下的对象数组:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

我试图通过匹配 name 键的值来缩小数组并实现所需的输出,例如:

desiredOutput = [
  {name: "qewregf dqewafs", data: [{value: "qewregf dqewafs answer", count: 2}]},
  {name: "survey with select", data: [{value: "survey with select answer", count: 2}]},
  {name: "werasd", data: [{value: "Donald", count: 1}, {value: "Jim", count: 1}]}
]

这个尝试减小了数组,但我不知道如何合并嵌套值而不会覆盖它们。

const arr = [{"name":"qewregf dqewafs","value":"qewregf dqewafs answer","count":2},{"name":"survey with select","value":"survey with select answer","count":2},{"name":"werasd","value":"Donald","count":1},{"name":"werasd","value":"Jim","count":1}];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  const value = { name: d.name, val: d.value };
  if (found) {
    acc.push(...value);
  }
  else {
    acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
  }
  return acc;
}, []);

console.log(result);

我缺失了什么?


你的代码实际上会因为 acc.push(...value); 抛出错误。应该改为 acc.push(value); - ibrahim mahrir
5个回答

23

你的代码已经很接近目标了,只需要做一些调整。

请查看下面演示中的注释:

  1. acc.find 没有找到任何内容时,将一个元素 {name:d.name, data: [value]} 推入数组。

  2. 如果找到,则将一个 {value: ...} 推入 data 属性中。

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  //const value = { name: d.name, val: d.value };
  const value = { value: d.value, count: d.count }; // the element in data property
  if (!found) {
    //acc.push(...value);
    acc.push({name:d.name, data: [value]}) // not found, so need to add data property
  }
  else {
    //acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
    found.data.push(value) // if found, that means data property exists, so just push new element to found.data.
  }
  return acc;
}, []);

console.log(result)


2
您离正确答案不远了。要完成这个目标,您只需更改代码中的两行即可:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  const found = acc.find(a => a.name === d.name);
  const value = { name: d.name, val: d.value };
  if (found) {
    found.data.push(value);
  }
  else {
    acc.push({ name: d.name, data: [{ value: d.value, count: d.count }] });
  }
  return acc;
}, []);

console.log(result)

以下是不同之处:
-     acc.push(...value);
+     found.data.push(value);


-    acc.push({ name: d.name, data: [{ value: d.value }, { count: d.count }] });
+    acc.push({ name: d.name, data: [{ value: d.value, count: d.count }] });

2

只需创建一个以名称为键的映射,并使用对象解构Object.values()来获取所需结果。

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

let result = Object.values(arr.reduce((a,{name, ...props})=>{
  if(!a[name])
     a[name]  = Object.assign({}, {name,data : [props]});
   else
    a[name].data.push(props);
  return a;
},{}));

console.log(result);


1
你可以通过检查找到的对象是否存在并将一个新对象推入结果集来简化使用该找到的对象。
然后将一个具有 "value" 和 "count" 的对象推入 "data" 中。

const
    array = [{ name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2 }, { name: "survey with select", value: "survey with select answer", count: 2 }, { name: "werasd", value: "Donald", count: 1 }, { name: "werasd", value: "Jim", count: 1 }],
    result = array.reduce((r, { name, value, count }) => {
        var temp = r.find(o => name === o.name);
        if (!temp) {
            r.push(temp = { name, data: [] });
        }
        temp.data.push({ value, count });
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


0
你需要像这样做:

const arr = [
  {name: "qewregf dqewafs", value: "qewregf dqewafs answer", count: 2},
  {name: "survey with select", value: "survey with select answer", count: 2},
  {name: "werasd", value: "Donald", count: 1},
  {name: "werasd", value: "Jim", count: 1}
];

const result = arr.reduce((acc, d) => {
  let idx = acc.findIndex(a => a.name === d.name);
  let val = { value: d.value, count: d.count };

  if (idx > -1) {
    acc[idx].data.push(val);
  } else {
    acc.push({ name: d.name, data: [val] });
  }

  return acc;
}, []);

console.log(result);

你需要先找到索引,然后将数据推入该行。你只是找到了它,但是却向数组中推送了一个新值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接