我有两个数组,如下所示:
const array1 = [
{
id: 'a1',
text: 'some text'
},
{
id: 'a2',
text: 'some more text',
},
{
id: 'a3',
text: 'some more text',
},
]
和
const array2 = [
{
id: 'a1',
text: 'some text'
},
{
id: 'ab12',
text: 'some text'
},
{
id: 'abc123',
text: 'some further text'
},
{
id: 'a3',
text: 'some more text'
},
{
id: 'bx44',
text: 'some more text'
},
]
我想将这些数组与必须结合每个数组是否具有与其他数组一样的“ id”属性的信息结合在一起,所以:
combined = [
{
id: 'a1',
text: 'some text',
info: 'in-both'
},
{
id: 'a2',
text: 'some text',
info: 'only-array1',
},
{
id: 'ab12',
text: 'some text',
info: 'only-array2',
},
{
id: 'abc123',
text: 'some further text',
info: 'only-array2',
},
{
id: 'a3',
text: 'some more text',
info: 'in-both',
},
{
id: 'bx44',
text: 'some more text',
info: 'only-array2',
},
]
我正在尝试保持“固有”顺序,以便仅出现在array1或array2中的项相对于它们的索引在匹配项(两个数组中的项)之间结束。例如,“ a2”(仅存在于array1中)在“ a1”之后但在“ a3”之前。如果在匹配之间,只有在array1或array2中存在多个项目,则我要尝试使属于array1的项目优先出现(在示例中,“ a2”在“ ab12”和“ abc123”之前)
到目前为止的代码:
array1.reduce((all, curr, a1index, a1array) => {
let correspondingItemInArray2Index = array2.findIndex(a2item => a2item.id === curr.id);
if(correspondingItemInArray2Index === -1) {
curr.info = 'only-in-array1';
}
else if(correspondingItemInArray2Index === a1index) {
// Items are on same level...
curr.info = 'in-both';
}
else {
... // I need to find all items of array2 until the next 'match' of ids?
}
}
, []);
答案 0 :(得分:2)
您可以获取常见项目并在所有项目之间进行迭代。
function merge(...data) {
var common = data.map(a => a.map(({ id }) => id)).reduce((a, b) => a.filter(v => b.includes(v))),
indices = data.map(_ => 0),
result = [];
while (indices.every((l, i) => l < data[i].length)) {
indices = indices.map((j, i) => {
while (j < data[i].length && !common.includes(data[i][j].id)) {
result.push(Object.assign({}, data[i][j++], { info: ['a', 'b'][i] }));
}
return j;
});
if (indices.some((l, i) => l >= data[i].length)) break;
result.push(Object.assign({}, data[0][indices[0]], { info: 'both' }));
indices = indices.map(v => v + 1);
}
indices.forEach((j, i) => {
while (j < data[i].length) {
result.push(Object.assign({}, data[i][j++], { info: ['a', 'b'][i] }));
}
});
return result;
}
var array1 = [{ id: 'a1', text: 'some text' }, { id: 'a2', text: 'some more text' }, { id: 'a3', text: 'some more text' }],
array2 = [{ id: 'a1', text: 'some text' }, { id: 'ab12', text: 'some text' }, { id: 'abc123', text: 'some further text' }, { id: 'a3', text: 'some more text' }, { id: 'bx44', text: 'some more text' }],
result = merge(array1, array2);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }