js数组对象合并

原数据:

let arr = [
    {
        time:'2022-05-第3周',
        name: undefined,
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        str: 0
    },
     {
        time:'2022-05-第3周',
        name: undefined,
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        str: 0
    },
     {
        time:'2022-05-第4周',
        name: undefined,
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        str: 0
    },
     {
        time:'2022-05-第4周',
        name: '失败',
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        str: 1
    },
     {
        time:'2022-05-第4周',
        name: '成功',
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        str: 1
    }
]

目标数据:


targetArr=[
    {
        name: '成功', //根据name合并str到data(相同time的str要相加)
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        data:[0,1]//根据time将相加后的str存入data(顺序就对应time顺序)
    },
    {
        name: '失败',
        type: 'bar',
        stack: 'Ad',
        label: {
            show: true,
            position: 'inside'
        },
        data:[0,1]
    }
]
阅读 1.4k
1 个回答
// 1. 如果 name 是 undefined 需要放到每个组
// 2. 如果某个 time 存在不是 undefined 的 name,那么 undefined 的会被忽略掉

// 把所有 name 不是 undefined 的找出来,产生一个 set
const validTimes = new Set(
    arr.filter(({ name }) => name !== undefined)
        .map(({ time }) => time)
);

// 把 validTimes 时间对应的 undefined 项排除掉
// 把不在 validTimes 中多余的项排除掉(仅保留一项)
const cache = new Set();
const cleanArr = arr.filter(({ time, name }) => {
    if (name !== undefined) { return true; }
    if (validTimes.has(time) || cache.has(time)) { return false; }
    cache.add(time);
    return true;
});
console.log(cleanArr);

// 做一个分组后的模板对象
const template = (({ time, str, ...props }) => props)(arr[0]);

// 先把 name 找出来,预定义分组
const groups = Object.fromEntries(
    [...new Set(cleanArr.map(({ name }) => name))]
        .filter(name => name !== undefined)
        .map(name => [
            name,
            {
                ...template,
                name,
                data: []
            }
        ])
);

// 预先把结果集取出来,因为后面可能多次使用
// 如果不是因为处理过程中要用,这个操作可以放在最后
// 之所以可以放在这里,因为引用的对象不会被替换掉,处理过程都是改的对象属性
const result = Object.values(groups);

// 最后遍历来拼 str
cleanArr.forEach(({ name, str }) => {
    if (name === undefined) {
        result.forEach(({ data }) => data.push(str));
    } else {
        groups[name].data.push(str);
    }
});

已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题