通过id组合对象数组,并减少其嵌套对象

时间:2019-03-09 00:08:31

标签: javascript typescript

我有一个对象数组(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')

1 个答案:

答案 0 :(得分: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; }