【问题标题】:JavaScript - Reduce Array of Objects by Key [duplicate]JavaScript - 按键减少对象数组[重复]
【发布时间】:2019-01-26 20:49:19
【问题描述】:

使用一组对象,例如:

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);

标签: javascript arrays javascript-objects


【解决方案1】:

你的代码有点接近目标,只是需要调整一些东西。

请看下面demo中的评论:

  1. acc.find没有找到任何东西时,推入一个元素{name:d.name, data: [value]}

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

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】:

    您可以通过检查找到的对象是否不存在并将新对象推送到结果集中来简化对它的使用。

    然后将带有valuecount 的对象推送到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; }

    【讨论】:

      【解决方案3】:

      你需要做这样的事情:

      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);

      您必须先找到索引,然后将数据推送到该行。您只是找到它,然后将新值推送到数组。

      【讨论】:

        【解决方案4】:

        离你不远了。这将是对两行代码的简单更改来实现它:

        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 }] });
        

        【讨论】:

          【解决方案5】:

          只需创建一个以名称为键的地图,并使用Object destructingObject.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);

          【讨论】:

            猜你喜欢
            • 2016-12-01
            • 2021-04-02
            • 2018-10-20
            • 2017-08-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-04-30
            • 2019-07-20
            相关资源
            最近更新 更多