我有两个以JSON格式查找的对象数组:
{
"Arr1":
[
{ "_id": "firstSub1", "count": 1, "price": 4 },
{ "_id": "firstSub2", "count": 2, "price": 7 },
{ "_id": "firstSub3", "count": 3, "price": 1 }
{ "_id": "firstSub4", "count": 4, "price": 1 }
],
"Arr2":
[
{ "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1 },
{ "name": "firstSub2" "date": 12 / 22 / 2011, "type": sometype2 },
{ "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3 }
{ "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 }
]
//Desired Output
"finalArray":
[
{ "name": "firstSub1", "date": 05 / 20 / 1998, "type": sometype1, "count": 1, "price": 4 },
{ "name": "firstSub2" "date": 12 / 22 / 2011, "type": sometype2, "count": 2, "price": 7 },
{ "name": "firstSub3", "date": 09 / 23 / 2004, "type": sometype3, "count": 3, "price": 1 },
{ "name": "firstSub9", "date": 09 / 23 / 2004, "type": sometype9 },
{ "_id": "firstSub4", "count": 4, "price": 1 }
]
}
我需要比较第一个数组中的_id
,看看是否与Arr2中的name
匹配,如果_id === name
匹配它们。
我尝试过使用lodash及其不需要的内容,并映射函数如下:
mergeArray() {
.... //pulling data
let Arr1 = data['Arr1Data'];
let Arr2 = data['Arr2Data'];
let finalArray = Arr2.map((e, _) =>
(_ = Arr1.find((q) => e.name === q._id)) ?
{ ...e, ..._ } : e)
console.log(finalArray)
}
来自Arr2的所有数据都回来并且仅与Arr1的一半数据合并我的数据没有返回所需的输出...我如何映射这两个数组并具有联合和交集?
使用vanilla Js,你可以从两个数组中获得一个独特的_id
和name
数组,循环遍历它并从迭代中匹配当前id
的两个数组中加入对象:
扣除了id
s和name
s的数组:
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
循环以连接两个数组中的元素:
const result = ids.map(e => ({
...Arr1.find(o => o._id === e),
...Arr2.find(o => o.name === e)
}))
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
const result = ids.map(e => ({
...Arr2.find(o => o.name === e),
...Arr1.find(o => o._id === e)
}))
console.log(result)
编辑:您可以在.map()
中调整返回的对象以删除属性(如_id
):
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}];
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}];
const ids = [...new Set([...Arr1.map(e => e._id), ...Arr2.map(e => e.name)])];
const result = ids.map(e => {
const obj = {
...Arr2.find(o => o.name === e),
...Arr1.find(o => o._id === e)
}
if(obj.name && obj._id) delete obj._id;
return obj;
})
console.log(result)
一种解决方案是使用Array.reduce()开始,accumulator
等于Arr2
(JSON.parse(JSON.stringify(Arr2))
)的副本,所以我们不会改变原始数组Arr2
。现在,在迭代Arr1
时,如果我们找到匹配,那么我们使用Object.assign()将相关属性添加到accumulator
上的关联对象,否则我们将整个对象放在accumulator
上:
const Arr1 = [
{"_id": "firstSub1", "count": 1, "price": 4},
{"_id": "firstSub2", "count": 2, "price": 7},
{"_id": "firstSub3", "count": 3, "price": 1},
{"_id": "firstSub4", "count": 4, "price": 1}
];
const Arr2 = [
{"name": "firstSub1", "date": "05/20/1998", "type": "sometype1"},
{"name": "firstSub2", "date": "12/22/2011", "type": "sometype2"},
{"name": "firstSub3", "date": "09/23/2004", "type": "sometype3"},
{"name": "firstSub9", "date": "09/23/2004", "type": "sometype9"}
];
let res = Arr1.reduce((acc, {_id, count, price}) =>
{
let fIdx = acc.findIndex(({name}) => name === _id);
if (fIdx >= 0)
Object.assign(acc[fIdx], {count, price});
else
acc.push({_id, count, price});
return acc;
}, JSON.parse(JSON.stringify(Arr2)));
console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
您可以按name
排序并比较i + 1
索引名称以验证是否应合并i + 1
索引和i
索引,或者对象是否没有用于合并的对。
例如,按name
排序意味着下一个对象/索引将是该对。
[{name: "firstSub1", count: 1}, {name: "firstSub1", date: "dd / mm / yyyy"}] // Pair found
要么
[{name: "firstSub1", count: 1}, {name: "firstSub2", count: 1}] // There is no a pair
这假设有最多一对
let obj = { "Arr1": [{ "_id": "firstSub1", "count": 1, "price": 4 }, { "_id": "firstSub2", "count": 2, "price": 7 }, { "_id": "firstSub3", "count": 3, "price": 1 }, { "_id": "firstSub4", "count": 4, "price": 1 } ], "Arr2": [{ "name": "firstSub1", "date": "05 / 20 / 1998", "type": "sometype1" }, { "name": "firstSub2", "date": "12 / 22 / 2011", "type": "sometype2" }, { "name": "firstSub3", "date": "09 / 23 / 2004", "type": "sometype3" }, { "name": "firstSub9", "date": "09 / 23 / 2004", "type": "sometype9" } ]};
// All objects in one array.
let merge = [...obj.Arr2,
// The map is to change _id by name, this is used later.
...obj.Arr1.map(({_id, count, price}) => ({name: _id, count, price}))]
.sort((a, b) => a.name.localeCompare(b.name));
// This approach doesn't mutate the source objects.
let result = [];
for (let i = 0; i < merge.length;) {
if (merge[i + 1] && merge[i + 1].name === merge[i].name) {
result.push(Object.assign(Object.create(null), merge[i], merge[i + 1]));
i++;
} else result.push(merge[i]);
i++;
}
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以使用lodash的_.flow()
创建一个组合数组的函数,通过name
或_id
(无论在对象上找到什么)对它们进行分组。如果a组包含多个项目,则它将合并为单个对象,并省略_id
属性。
const { flow, partialRight: pr, concat, groupBy, map, merge, has, head, omit } = _
const fn = flow(
concat, // combine to a single array
pr(groupBy, o => o.name || o._id), // group by the value of name or _id
pr(map, o => o.length === 1 ? head(o) : _.omit( // if a group contains 2 items merge them, and remove _id
merge({}, ...o),
'_id'
)),
)
const Arr1 = [{"_id": "firstSub1","count": 1,"price": 4},{"_id": "firstSub2","count": 2,"price": 7},{"_id": "firstSub3","count": 3, "price": 1}, {"_id": "firstSub4","count": 4,"price": 1}]
const Arr2 = [{"name": "firstSub1","date": "05 / 20 / 1998","type": "sometype1"}, {"name": "firstSub2","date": "12 / 22 / 2011","type": "sometype2"}, {"name": "firstSub3","date": "09 / 23 / 2004","type": "sometype3"}, {"name": "firstSub9","date": "09 / 23 / 2004","type": "sometype9"}]
const result = fn(Arr2, Arr1)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>