【问题标题】:combine an array of object by id and and reduce its nested object按 id 组合对象数组并减少其嵌套对象
【发布时间】:2019-03-09 10:27:03
【问题描述】:

我有一个对象数组(old_array)需要合并成为(new_array)

old_array = [
        { id: 'ffff55', name: 'f5', card: 'a', request: { device: 0, bus: 1, ship: 21 } },
        { id: 'vvvv44', name: 'v4', card: 'c', request: { device: 3, bus: 10, ship: 2 } },
        { id: 'cccc33', name: 'c3', card: 'a', request: { device: 0, bus: 1, ship: 2 } },
        { id: 'ffff55', name: 'f5', card: 'b', request: { device: 32, bus: 31, ship: 32 } },
        { id: 'cccc33', name: 'c3', card: 'e', request: { device: 21, bus: 21, ship: 22 } },
        { id: 'cccc33', name: 'c3', card: 'd', request: { device: 4, bus: 1, ship: 2 } },
        { id: 'vvvv44', name: 'v4', card: 'c', request: { device: 13, bus: 11, ship: 12 } }
    ];

new_array = [
        { id: 'ffff55', name: 'f5', unique_cards: 2, request: { device: 32, bus: 32, ship: 53 } },
        { id: 'vvvv44', name: 'v4', unique_cards: 1, request: { device: 16, bus: 21, ship: 14 } },
        { id: 'cccc33', name: 'c3', unique_cards: 3, request: { device: 25, bus: 23, ship: 26 } }
    ];
  • 将具有相同id和名称的对象合并到一个对象中
  • 合并嵌套请求对象(其值的总和)
  • 将卡片映射到唯一卡片的数量(按 id)

我已经连续尝试了 4 天,但是这个数组操作很难

我最好的尝试是尝试按 id 对对象数组进行分组,但它会因为许多冗余值而变得更加复杂

groupByArray(xs, key) {
        return xs.reduce(function(rv, x) {
            let v = key instanceof Function ? key(x) : x[key];
            let el = rv.find((r) => r && r.key === v);
            if (el) {
                el.values.push(x);
            } else {
                rv.push({ key: v, values: [ x ] });
            }
            return rv;
        }, []);
    }

groupByArray(old_array , 'id')

【问题讨论】:

  • 展示你在js中的最佳尝试
  • @zerkms 我尝试按 id 对数组进行分组,然后映射和减少,但它变得更复杂(更多嵌套对象)
  • 您列举了 3 个不同的任务。尝试仅解决第一个问题并发布您的最佳尝试。这确实是一个非常频繁的请求:至少做一个研究。
  • @zerkms 我只问我是否非常绝望。我发现的关于合并的大部分内容要么是一个简单的数组,要么是使用 underscore.js loddah 和其他东西。今天连续 14 小时搜索
  • "要么是一个简单的数组" --- 你有一个简单对象的简单数组。这里的问题是,现在您有了答案,但您仍然无法解决此类任务。你确实可以复制粘贴,但明天条件稍有变化你又会卡住????

标签: javascript typescript


【解决方案1】:

您可以使用函数reduce进行分组,使用函数Object.values提取分组的对象。

在 reduce 的处理程序中,您需要遍历请求的键以便对每个值求和。

let array = [        { id: 'ffff55', name: 'f5', card: 'a', request: { device: 0, bus: 1, ship: 21 } },        { id: 'vvvv44', name: 'v4', card: 'c', request: { device: 3, bus: 10, ship: 2 } },        { id: 'cccc33', name: 'c3', card: 'a', request: { device: 0, bus: 1, ship: 2 } },        { id: 'ffff55', name: 'f5', card: 'b', request: { device: 32, bus: 31, ship: 32 } },        { id: 'cccc33', name: 'c3', card: 'e', request: { device: 21, bus: 21, ship: 22 } },        { id: 'cccc33', name: 'c3', card: 'd', request: { device: 4, bus: 1, ship: 2 } },        { id: 'vvvv44', name: 'v4', card: 'c', request: { device: 13, bus: 11, ship: 12 } }    ];
let result = Object.values(array.reduce((a, {id, name, card, request}) => {
  (a[id] || (a[id] = {id, card, name, unique_cards: 1, request: {}}));
  
  if (a[id].card !== card) {
    a[id].unique_cards++;
    a[id].card = card;
  }
  
  Object.keys(request).forEach(k => a[id].request[k] = (a[id].request[k] || 0) + request[k]); 
  return a;
}, Object.create(null)));

result.forEach(o => delete o.card);

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

【讨论】:

  • @AmineDa。你是对的,所以你需要检查最后一张验证卡的价值来增加计数器。看到更新的答案,不幸的是,最后一步应该是循环结果并删除card属性。
  • @AmineDa。基本上,我要的是id 之前捕获的对象。所以,如果a[id] 与 undefined 不同意味着我之前得到了一个对象,所以我需要处理它,否则,是一个我之前没有得到的新 id,所以我应该创建所需的对象结构。跨度>
  • @.Ele 还有一件事。我不明白 a[id].card = card inside if 的意义
  • @AmineDa。这就像一个面包屑,因为我需要知道之前检查的卡是否不同才能增加计数。
  • 是的,但我们应该检查“a[id].card”的整个数组,而不仅仅是最后一个值。如果我使用旧卡向数组中添加一个对象,它将被视为唯一
猜你喜欢
  • 2021-12-28
  • 1970-01-01
  • 2018-01-12
  • 2018-05-30
  • 2023-02-07
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2019-03-26
相关资源
最近更新 更多