如何比较 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