使用相同的键合并来自不同对象的数组

Merge arrays from different objects with same key

我有以下代码:

const blueData = {
    "items": [
        {
            "id": 35,
            "revision": 1,
            "updatedAt": "2021-09-10T14:29:54.595012Z",
        },
    ]
}

const redData = {}

const greenData = {
    "items": [
        {
            "id": 36,
            "revision": 1,
            "updatedAt": "2021-09-10T14:31:07.164368Z",
        }
    ]
}

let colorData = []
colorData = blueData.items ? [colorData, ...blueData.items] : colorData
colorData = redData.items ? [colorData, ...redData.items] : colorData
colorData = greenData.items ? [colorData, ...greenData.items] : colorData

我猜展开运算符在这里不是正确的方法,因为我在最终的 colorData 数组中得到了一些额外的数组。我只想构建一个 'items' 数组,其中包含 3 个对象中的所有 'items'。

这是 es6 控制台中该代码的 link:https://es6console.com/ktkhc3j2/

像这样?

colorData = blueData.items ? [...colorData, ...blueData.items] : colorData
colorData = redData.items ? [...colorData, ...redData.items] : colorData
colorData = greenData.items ? [...colorData, ...greenData.items] : colorData

输出:

[{"id":35,"revision":1,"updatedAt":"2021-09-10T14:29:54.595012Z"}, 
{"id":36,"revision":1,"updatedAt":"2021-09-10T14:31:07.164368Z"}]

我认为您还需要将扩展​​运算符添加到 colorData 数组,因为如果不这样做,您将添加 colorData 数组本身,而不是它的项。

您可以使用 Logical OR operator 执行此操作,如果缺少 items 字段,您可以提供默认值。

const blueData = { items: [ { id: 35, revision: 1, updatedAt: '2021-09-10T14:29:54.595012Z', }, ], };
const redData = {};
const greenData = { items: [ { id: 36, revision: 1, updatedAt: '2021-09-10T14:31:07.164368Z', }, ], };

const colorData = [
  ...(blueData.items || []),
  ...(redData.items || []),
  ...(greenData.items || []),
];

console.log(colorData);

如果你想要最简单的解决方案,你可以在所有数组之间使用for循环进行迭代。创建一个临时数组,用于存储在每个索引上找到的数据。这是最快和最灵活的解决方案。

var x1 = {
  "items": [
    { "testKey1": "testVal" }
  ] 
};

var x2 = {
  "items": [
    { "testKey2.0": "testVal2" },
    { "testKey2.1": "testVal2" },
    { "testKey2.2": "testVal2" },
  ] 
};

var x3 = {
  "items": [
    { "testKey3.0": "testVal3" },
    { "testKey3.1": "testVal3" }
  ] 
};

function combineArrays(...arrays) {

  var tempArray = [];
  for (let index in arrays) {
    let currentArray = arrays[index];
    for (let innerArrayIndex in currentArray) {
      tempArray.push(currentArray[innerArrayIndex]);
    }
  } 
  
  return tempArray;
}

var result = combineArrays(x1.items, x2.items, x3.items);
console.log(result);

使用展开运算符的解决方案没有考虑到所有对象都将使用浅拷贝进行克隆。 Have a look.

也许我有点老套,但我会使用 concat

The concat() method is used to merge two or more arrays. This method does not change the existing arrays, but instead returns a new array. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

const blueData = {
    "items": [
        {
            "id": 35,
            "revision": 1,
            "updatedAt": "2021-09-10T14:29:54.595012Z",
        },
    ]
}

const redData = {}

const greenData = {
    "items": [
        {
            "id": 36,
            "revision": 1,
            "updatedAt": "2021-09-10T14:31:07.164368Z",
        }
    ]
}


const colorData = [].concat(blueData.items,redData.items,greenData.items).filter(x => x)

console.log(colorData)

最后一个 filter 用于删除未定义的值

将您的数据放入数组中,然后使用 flatMap 解包每个 .items:

[greenData, redData, blueData].flatMap(d => d.items ?? [])
//=> [ {id: 36, revision: 1, updatedAt: '2021-09-10T14:31:07.164368Z'}
//=> , {id: 35, revision: 1, updatedAt: '2021-09-10T14:29:54.595012Z'}]

如果你喜欢,你可以用一点咖喱来抽象 d => d.items ?? [](没有双关语的意思;)

const take = k => o => o[k] ?? [];

这给了我们:

[greenData, redData, blueData].flatMap(take('items'))

如果您需要使用不同的密钥重复此过程,我们甚至可以更进一步:

const concatBy = fn => xs => xs.flatMap(x => fn(x));

现在感觉就像您是在用文字而不是代码来表达您的意图:

const takeItems = concatBy(take('items'));

takeItems([greenData, redData, blueData]);
//=> [ {id: 36, revision: 1, updatedAt: '2021-09-10T14:31:07.164368Z'}
//=> , {id: 35, revision: 1, updatedAt: '2021-09-

让我们构建另一个函数:

const takeFood = concatBy(take('food'));

takeFood([{food: ['', '']}, {food: ['', '']}]);
//=> ['', '', '', '']

附录

这只是一个可能有用的学习 material。我的建议是使用 flatMap.

这个:

[[1, 2], [3, 4]].flatMap(x => x)
//=> [1, 2, 3, 4]

也可以用reduce表示。稍微冗长一点,但确实如锡罐上所说:

[[1, 2], [3, 4]].reduce((xs, x) => xs.concat(x), [])
//=> [1, 2, 3, 4]

简而言之,您还可以这样做:

[greenData, redData, blueData].reduce((xs, x) => xs.concat(x.items ?? []), [])