H5W3
当前位置:H5W3 > 问答 > 正文

如何让多个对象相同的属性值相加

    var data = [
{
typeId: '2',
name: 'potato',
number: 16
},
{
typeId: '3',
name: 'potato',
number: 10
},
{
typeId: '4',
name: 'tomato',
number: 4
},
{
typeId: '5',
name: 'tomato',
number: 21
},
{
typeId: '6',
name: 'vegetables',
number: 3
},
{
typeId: '7',
name: 'vegetables',
number: 13
},
]
转换成以下数据 arr数据
arr = [
{
typeId: ["6", "7"],
name: 'vegetables',
number: 16
},
{
typeId: ["4", "5"],
name: 'tomato',
number: 25
},
{
typeId: ["2", "3"],
name: 'potato',
number: 26
}
]

把 数组 data中的子对象中 name属性相同的子对象的 number 合并,得到一个新的对象,从而返回一个新数组 arr, 有哪些比较好的方法?

回答

var data = [
      {
        typeId: '2',
        name: 'potato',
        number: 16
      },
      {
        typeId: '3',
        name: 'potato',
        number: 10
      },
      {
        typeId: '4',
        name: 'tomato',
        number: 4
      },
      {
        typeId: '5',
        name: 'tomato',
        number: 21
      },
      {
        typeId: '6',
        name: 'vegetables',
        number: 3
      },
      {
        typeId: '7',
        name: 'vegetables',
        number: 13
      },
    ]
      let arr = []
      data.map((el,i) => {

          if(!arr.some(el2 => el2.name === el.name)){
            arr.push({
                typeId:[el.typeId],
                name:el.name,
                number:el.number
            })
          }else{
              let obj = arr.find(v => v.name === el.name)
              obj.typeId.push(el.typeId)
              obj.number = obj.number + el.number
          }
      })
      console.log(arr)
const res = [];
data.map((ele, index, arr) => {
    if (!res.find(newE => ele.name == newE.name)) {
        let typeArr = [ele.typeId]
        let num = ele.number;
        for (let i in arr) {
            if (ele.name == arr[i].name && i != index) {
                typeArr.push(arr[i].typeId);
                num += arr[i].number;
            }
        }
        ele.typeId = typeArr;
        ele.number = num;
        res.push(ele);
    }
})

console.log(res);
const subscripts = {};
const result = [];

data.forEach(({ name, typeId, number }) => {
    const idx = subscripts[name];
    
    if (typeof idx === 'number') {
        result[idx].number += number;
        result[idx].typeId.push(typeId);
    } else {
        subscripts[name] = result.length;
        result.push({ typeId: [typeId], name, number });
    }
});
function concatSameProp (data) {
  return data.reduce((prev, cur) => {
    if (!prev.length || !prev.filter(x => x.name === cur.name).length) {
      cur.typeId = cur.typeId.split('')
      prev.push(cur)
      return prev
    } else {
      const idx = prev.findIndex(x => x.name === cur.name)
      prev[idx].typeId.push(cur.typeId)
      prev[idx].number += cur.number
      return prev
    }
  }, [])
}

concatSameProp(data)

GroupBy 啊。会写 groupBy 之后你可以回答 js 话题下的大部分 json 遍历转化问题。

不知道将来 JS 的数组会不会加原生的 GroupBy 实现。

// 这个 groupBy 函数是通用的,无论需求怎么变,groupBy的实现不会变
function groupBy(arr, by) {
    return arr.reduce((groups, item) => {
        // 获取 item 的分组的 key
        const key = by(item);
        // 看看这个组是不是已经存在
        let group = groups.find(g => g.key === key);
        if(!group) {
            // 不存在就创建一个新组
            group = {key, items: []};
            groups.push(group);
        }
        // item 放入组中
        group.items.push(item);
        return groups;
    }, []);
}

// 就是 SQL 的翻版嘛
// select name, sum(number) from data group by name
groupBy(data, item => item.name)
    .map(g => ({
        name: g.key,
        typeId: g.items.map(item => item.typeId),
        number: g.items.reduce((sum, item) => sum + item.number, 0)
    }));

未经允许不得转载:H5W3 » 如何让多个对象相同的属性值相加

赞 (0)

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址