如何比较 Javascript 和 return 中缺少元素的 2 个数组中的对象?
How can I compare objects in 2 arrays in Javascript & return the missing elements?
有没有办法将不完整的数组与真实数组的来源和 return 缺失的元素进行比较?该数组由对象组成,一些对象有一个对象数组。
let incompleteArr =[
{
"name": "Extra Toppings (Small)",
"modifier_options": [{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 0.9
},
{
"name": "Onion",
"price": 0.45
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra Mozzarella",
"price": 1.7
}
]
}
]
}]
let completeArr =[
{
"name": "Extra Toppings (Small)",
"modifier_options": [
{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 1.2
},
{
"name": "Extra Anchovies",
"price": 0.7
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [
{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra mozzarella",
"price": 1.7
}
]
},
{
"name": "Extra Burger Toppings (Small)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.5
},
{
"name": "Extra Tomato",
"price": 0.55
},
{
"name": "Extra Cheese",
"price": 0.65
},
{
"name": "Extra Mayo",
"price": 0.3
},
{
"name": "Extra Patty",
"price": 2.5
}
]
},
{
"name": "Extra Burger Toppings (Medium)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.6
},
{
"name": "Extra Tomato",
"price": 0.65
},
{
"name": "Extra Cheese",
"price": 0.75
},
{
"name": "Extra Mayo",
"price": 0.4
},
{
"name": "Extra Patty",
"price": 2.9
}
]
},
{
"name": "Extra Burger Toppings (Large)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.8
},
{
"name": "Extra Tomato",
"price": 0.9
},
{
"name": "Extra Cheese",
"price": 0.95
},
{
"name": "Extra Mayo",
"price": 0.6
},
{
"name": "Extra Patty",
"price": 3.5
}
]
}
]
期望的结果是 return 缺少元素的数组。例如,“名称”Extra Toppings (Small) 必须存在于 incompleteArr 和 completeArr 中。然后还必须比较“modifier_options”。任何不在 incompleteArr 中的 modifier_options 必须被推入缺失元素的数组中。
到目前为止我已经试过了
let missingMod = gfMods.filter(mod => lvMods.every(mod2 => !mod2.name.includes(mod.name)))
预期的输出是缺失项,但我没有从 modifier_options 对象中获取缺失的嵌套数组项。我有一个想法,我需要遍历数组以检查“名称”是否存在,然后进行第二个循环以检查 modifier_options 是否全部存在。这就是我一直被卡住的地方。
[{
name:"Extra Burger Toppings (Small)",
modifier_options: [{
name:"Extra Onion",
price:0.5},
{name:"Extra Tomato",
price:0.55},
{name:"Extra Cheese",
price:0.65},
{name:"Extra Mayo",
price:0.3},
{name:"Extra Patty",
price:2.5}
]},
{name:"Extra Burger Toppings (Medium)",
modifier_options: [{
name:"Extra Onion",
price:0.6},
{name:"Extra Tomato",
price:0.65},
{name:"Extra Cheese",
price:0.75},
{name:"Extra Mayo",
price:0.4},
{name:"Extra Patty",
price:2.9}]
},
{name:"Extra Burger Toppings (Large)",
modifier_options: [{
name:"Extra Onion",
price:0.8},
{name:"Extra Tomato",
price:0.9},
{name:"Extra Cheese",
price:0.95},
{name:"Extra Mayo",
price:0.6},
{name:"Extra Patty",
price:3.5}]
}]
此解决方案利用 the .reduce()
, .find()
, .some()
, and .filter()
Array methods。
// Reduces the complete array, to a list of missing values from
// the incomplete array.
const result = completeArr.reduce((prev, next) => {
// Finds whether the object exists in the incomplete array.
// _main will hold the matching object from the incomplete
// array if found, or undefined otherwise.
const _main = incompleteArr.find(obj => obj.name == next.name);
// If it does find, stop here and check for missing
// values inside modifier options.
if(_main){
// .filter to get the missing modifier objects from the
// incomplete array. Done by checking if a
// modifier option of the complete array
// is NOT present in the incomplete array's
// modifier options list.
const _mod = next.modifier_options.filter(next_mod => !_main.modifier_options.some(main_mod => next_mod.name == main_mod.name));
// Add _mod(containing missing modifier options) to
// the accumulating array and return.
return [...prev, {parent: next.name, modifier_options: _mod}];
}
// This next object doesn't exist in the incomplete
// array as it wasn't found, so add it to the accumulating
// list of missing items.
return [...prev, next];
}, []);
let incompleteArr = [
{
"name": "Extra Toppings (Small)",
"modifier_options": [{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 0.9
},
{
"name": "Onion",
"price": 0.45
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra Mozzarella",
"price": 1.7
}
]
}
];
let completeArr = [
{
"name": "Extra Toppings (Small)",
"modifier_options": [
{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 1.2
},
{
"name": "Extra Anchovies",
"price": 0.7
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [
{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra mozzarella",
"price": 1.7
}
]
},
{
"name": "Extra Burger Toppings (Small)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.5
},
{
"name": "Extra Tomato",
"price": 0.55
},
{
"name": "Extra Cheese",
"price": 0.65
},
{
"name": "Extra Mayo",
"price": 0.3
},
{
"name": "Extra Patty",
"price": 2.5
}
]
},
{
"name": "Extra Burger Toppings (Medium)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.6
},
{
"name": "Extra Tomato",
"price": 0.65
},
{
"name": "Extra Cheese",
"price": 0.75
},
{
"name": "Extra Mayo",
"price": 0.4
},
{
"name": "Extra Patty",
"price": 2.9
}
]
},
{
"name": "Extra Burger Toppings (Large)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.8
},
{
"name": "Extra Tomato",
"price": 0.9
},
{
"name": "Extra Cheese",
"price": 0.95
},
{
"name": "Extra Mayo",
"price": 0.6
},
{
"name": "Extra Patty",
"price": 3.5
}
]
}
];
const result = completeArr.reduce((prev, next) => {
const _main = incompleteArr.find(obj => obj.name == next.name);
if(_main){
const _mod = next.modifier_options.filter(next_mod => !_main.modifier_options.some(main_mod => next_mod.name == main_mod.name));
return [...prev, {parent: next.name, modifier_options: _mod}];
}
return [...prev, next];
}, []);
console.log(result);
注意: return “额外的马苏里拉奶酪” 来自 “额外的配料(大)" 因为大小写不同。另外,请原谅糟糕的变量名,我希望这个解决方案能解决你的问题。
更新
根据OP的要求,我添加了缺失的modifier_options
所属父对象的.name
。
有没有办法将不完整的数组与真实数组的来源和 return 缺失的元素进行比较?该数组由对象组成,一些对象有一个对象数组。
let incompleteArr =[
{
"name": "Extra Toppings (Small)",
"modifier_options": [{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 0.9
},
{
"name": "Onion",
"price": 0.45
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra Mozzarella",
"price": 1.7
}
]
}
]
}]
let completeArr =[
{
"name": "Extra Toppings (Small)",
"modifier_options": [
{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 1.2
},
{
"name": "Extra Anchovies",
"price": 0.7
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [
{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra mozzarella",
"price": 1.7
}
]
},
{
"name": "Extra Burger Toppings (Small)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.5
},
{
"name": "Extra Tomato",
"price": 0.55
},
{
"name": "Extra Cheese",
"price": 0.65
},
{
"name": "Extra Mayo",
"price": 0.3
},
{
"name": "Extra Patty",
"price": 2.5
}
]
},
{
"name": "Extra Burger Toppings (Medium)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.6
},
{
"name": "Extra Tomato",
"price": 0.65
},
{
"name": "Extra Cheese",
"price": 0.75
},
{
"name": "Extra Mayo",
"price": 0.4
},
{
"name": "Extra Patty",
"price": 2.9
}
]
},
{
"name": "Extra Burger Toppings (Large)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.8
},
{
"name": "Extra Tomato",
"price": 0.9
},
{
"name": "Extra Cheese",
"price": 0.95
},
{
"name": "Extra Mayo",
"price": 0.6
},
{
"name": "Extra Patty",
"price": 3.5
}
]
}
]
期望的结果是 return 缺少元素的数组。例如,“名称”Extra Toppings (Small) 必须存在于 incompleteArr 和 completeArr 中。然后还必须比较“modifier_options”。任何不在 incompleteArr 中的 modifier_options 必须被推入缺失元素的数组中。
到目前为止我已经试过了
let missingMod = gfMods.filter(mod => lvMods.every(mod2 => !mod2.name.includes(mod.name)))
预期的输出是缺失项,但我没有从 modifier_options 对象中获取缺失的嵌套数组项。我有一个想法,我需要遍历数组以检查“名称”是否存在,然后进行第二个循环以检查 modifier_options 是否全部存在。这就是我一直被卡住的地方。
[{
name:"Extra Burger Toppings (Small)",
modifier_options: [{
name:"Extra Onion",
price:0.5},
{name:"Extra Tomato",
price:0.55},
{name:"Extra Cheese",
price:0.65},
{name:"Extra Mayo",
price:0.3},
{name:"Extra Patty",
price:2.5}
]},
{name:"Extra Burger Toppings (Medium)",
modifier_options: [{
name:"Extra Onion",
price:0.6},
{name:"Extra Tomato",
price:0.65},
{name:"Extra Cheese",
price:0.75},
{name:"Extra Mayo",
price:0.4},
{name:"Extra Patty",
price:2.9}]
},
{name:"Extra Burger Toppings (Large)",
modifier_options: [{
name:"Extra Onion",
price:0.8},
{name:"Extra Tomato",
price:0.9},
{name:"Extra Cheese",
price:0.95},
{name:"Extra Mayo",
price:0.6},
{name:"Extra Patty",
price:3.5}]
}]
此解决方案利用 the .reduce()
, .find()
, .some()
, and .filter()
Array methods。
// Reduces the complete array, to a list of missing values from
// the incomplete array.
const result = completeArr.reduce((prev, next) => {
// Finds whether the object exists in the incomplete array.
// _main will hold the matching object from the incomplete
// array if found, or undefined otherwise.
const _main = incompleteArr.find(obj => obj.name == next.name);
// If it does find, stop here and check for missing
// values inside modifier options.
if(_main){
// .filter to get the missing modifier objects from the
// incomplete array. Done by checking if a
// modifier option of the complete array
// is NOT present in the incomplete array's
// modifier options list.
const _mod = next.modifier_options.filter(next_mod => !_main.modifier_options.some(main_mod => next_mod.name == main_mod.name));
// Add _mod(containing missing modifier options) to
// the accumulating array and return.
return [...prev, {parent: next.name, modifier_options: _mod}];
}
// This next object doesn't exist in the incomplete
// array as it wasn't found, so add it to the accumulating
// list of missing items.
return [...prev, next];
}, []);
let incompleteArr = [
{
"name": "Extra Toppings (Small)",
"modifier_options": [{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 0.9
},
{
"name": "Onion",
"price": 0.45
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra Mozzarella",
"price": 1.7
}
]
}
];
let completeArr = [
{
"name": "Extra Toppings (Small)",
"modifier_options": [
{
"name": "Corn",
"price": 0.75
},
{
"name": "Extra mozzarella",
"price": 1.2
},
{
"name": "Extra Anchovies",
"price": 0.7
}
]
},
{
"name": "Extra Toppings (Large)",
"modifier_options": [
{
"name": "Corn",
"price": 1.2
},
{
"name": "Extra mozzarella",
"price": 1.7
}
]
},
{
"name": "Extra Burger Toppings (Small)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.5
},
{
"name": "Extra Tomato",
"price": 0.55
},
{
"name": "Extra Cheese",
"price": 0.65
},
{
"name": "Extra Mayo",
"price": 0.3
},
{
"name": "Extra Patty",
"price": 2.5
}
]
},
{
"name": "Extra Burger Toppings (Medium)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.6
},
{
"name": "Extra Tomato",
"price": 0.65
},
{
"name": "Extra Cheese",
"price": 0.75
},
{
"name": "Extra Mayo",
"price": 0.4
},
{
"name": "Extra Patty",
"price": 2.9
}
]
},
{
"name": "Extra Burger Toppings (Large)",
"modifier_options": [
{
"name": "Extra Onion",
"price": 0.8
},
{
"name": "Extra Tomato",
"price": 0.9
},
{
"name": "Extra Cheese",
"price": 0.95
},
{
"name": "Extra Mayo",
"price": 0.6
},
{
"name": "Extra Patty",
"price": 3.5
}
]
}
];
const result = completeArr.reduce((prev, next) => {
const _main = incompleteArr.find(obj => obj.name == next.name);
if(_main){
const _mod = next.modifier_options.filter(next_mod => !_main.modifier_options.some(main_mod => next_mod.name == main_mod.name));
return [...prev, {parent: next.name, modifier_options: _mod}];
}
return [...prev, next];
}, []);
console.log(result);
注意: return “额外的马苏里拉奶酪” 来自 “额外的配料(大)" 因为大小写不同。另外,请原谅糟糕的变量名,我希望这个解决方案能解决你的问题。
更新
根据OP的要求,我添加了缺失的modifier_options
所属父对象的.name
。