javascript - 将两个数组与公共对象合并
问题描述
我正在做一个从服务器获取数据的项目,每个数据都必须是这种格式
const DATA = [
{
title: {title: 'Main dishes'},
data: [
{_id: 1, type: 'Pizza'},
{_id: 2, type: 'Burger'},
{_id: 3, type: 'Risotto'},
],
},
{
title: {title: 'Sides'},
data: [
{_id: 4, type: 'French Fries'},
{_id: 5, type: 'Onion Rings'},
{_id: 6, type: 'Fried Shrimps'},
],
},
];
但我的问题有时会在两次或三次提取中得到相同的标题对象,所以我需要在它们之间合并并隐藏重复的数据我正在使用这个函数
merged = (data1, data2) => {
let arr = data1.concat(data2);
let titles = new Map(arr.map(({title}) => [title, new Map()]));
arr.forEach(({title, data}) => {
let map = titles.get(title);
data.forEach(o => map.set(o._id, o));
});
return Array.from(titles.entries(), ([title, map]) => ({
title,
data: [...map.values()],
}));
};
但问题是此函数仅在对象中的标题是字符串时才有效
例子 :
const DATA = [
{
title: {title: 'Main dishes'},
data: [
{_id: 1, type: 'Pizza'},
{_id: 2, type: 'Burger'},
{_id: 3, type: 'Risotto'},
],
},
{
title: {title: 'Sides'},
data: [
{_id: 4, type: 'French Fries'},
{_id: 5, type: 'Onion Rings'},
{_id: 6, type: 'Fried Shrimps'},
],
},
];
const DATA2 = [
{
title: {title: 'Sides'},
data: [{_id: 7, type: 'Lemon'}],
},
{
title: {title: 'Drinks'},
data: [
{_id: 8, type: 'Water'},
{_id: 9, type: 'Coke'},
{_id: 10, type: 'Beer'},
],
},
{
title: {title: 'Desserts'},
data: [
{_id: 11, type: 'Cheese Cake'},
{_id: 12, type: 'Ice Cream'},
],
},
];
must give me an array like this
data = [
{
title: {title: 'Main dishes'},
data: [
{_id: 1, type: 'Pizza'},
{_id: 2, type: 'Burger'},
{_id: 3, type: 'Risotto'},
],
},
{
title: {title: 'Sides'},
data: [
{_id: 4, type: 'French Fries'},
{_id: 5, type: 'Onion Rings'},
{_id: 6, type: 'Fried Shrimps'},
{_id: 7, type: 'Lemon'},
],
},
{
title: {title: 'Drinks'},
data: [
{_id: 8, type: 'Water'},
{_id: 9, type: 'Coke'},
{_id: 10, type: 'Beer'},
],
},
{
title: {title: 'Desserts'},
data: [
{_id: 11, type: 'Cheese Cake'},
{_id: 12, type: 'Ice Cream'},
],
},
]
那么任何人都可以向我提出一个如何编辑该功能的解决方案吗?谢谢你
解决方案
那是因为{title: 'foo-bar'}
当你这样做时,每个对象都是通过引用titles.get(title)
而不是它们的值来检查的。
要么将地图中的字符串标题保存titles
为键,要么使用object-hash
将对象转换为标识符之类的东西。
使用字符串键:
merged = (data1, data2) => {
let arr = data1.concat(data2);
let titles = new Map(arr.map(({title}) => [title.title, new Map()])); // notice the `title.title` instead of `title`
arr.forEach(({title, data}) => {
let map = titles.get(title.title); // `title.title` instead of `title`
data.forEach(o => map.set(o._id, o));
});
return Array.from(titles.entries(), ([title, map]) => ({
title,
data: [...map.values()],
}));
};
并使用object-hash
:
import hash from 'object-hash';
merged = (data1, data2) => {
let arr = data1.concat(data2);
let titles = new Map(arr.map(({title}) => [hash(title), new Map()]));
arr.forEach(({title, data}) => {
let map = titles.get(hash(title));
data.forEach(o => map.set(o._id, o));
});
return Array.from(titles.entries(), ([title, map]) => ({
title,
data: [...map.values()],
}));
};
请注意,在这种情况下,对对象进行散列可能会过大。我认为字符串解决方案就足够了。
推荐阅读
- concurrency - CompletableFuture.allOf,记录并重新抛出异常
- backend - 包含用户特定数据的 Dialogflow
- python - 计算熊猫数据框中最近邻居的平均距离
- apache-spark - 最新 Parquet 版本的 Spark
- javascript - React Redux ActionCreator fetch API 总是会成功,即使 fetch 失败
- .net - 无法从引用的 dll 调用函数
- junit5 - 如何用junit5定义@Rule和@ClassRule
- javascript - Framework7 Stepper buttons not working
- php - Angular 6 HttpClient 和 PHP 错误(未知 url)的 Http 失败响应:0 未知错误
- android - onSaveInstanceState 后无法执行此操作 - android