0

我有两个包含嵌套对象的数组。我想合并这些并获得一个独特的数组

我有这两个数组

// ARRAY 1
let variants = [
  {color: "Red", sizes: "Small", material: "Cotton", price: "$100", ...},
  {color: "Red", sizes: "Large", material: "Cotton", price: "$120", ...},
  {color: "Blue", sizes: "Small", material: "Cotton", price: "$150", ...},
  {color: "Blue", sizes: "Large", material: "Cotton", price: "$180", ...},
]
// ARRAY 2
let newVariants = [
  {color: "Red", sizes: "Small", material: "Cotton"}, // this one is already exist in ARRAY 1
  {color: "Red", sizes: "Large", material: "Cotton"}, // this one is already exist in ARRAY 1
  {color: "Blue", sizes: "Small", material: "Cotton"}, // this one is already exist in ARRAY 1
  {color: "Blue", sizes: "Large", material: "Wool"}, // this one is new object
  {color: "Green", sizes: "Large", material: "Cotton"}, // this one is new object
]

我想要这个

[
  {color: "Red", sizes: "Small", material: "Cotton", price: "$100"},
  {color: "Red", sizes: "Large", material: "Cotton", price: "$120"},
  {color: "Blue", sizes: "Small", material: "Cotton", price: "$150"},
  {color: "Blue", sizes: "Large", material: "Cotton", price: "$180"},
  {color: "Blue", sizes: "Large", material: "Wool", price: null, ...},
  {color: "Green", sizes: "Large", material: "Cotton", price: null, ...}
]

注意:ARRAY 1 的值将始终取代 ARRAY 2

谢谢!

4

4 回答 4

2

ARRAY 1 的值将始终取代 ARRAY 2

您可以使用以下过滤器进行.filter过滤.some

let variants = [ {color: "Red", sizes: "Small", material: "Cotton", price: "$100",}, {color: "Red", sizes: "Large", material: "Cotton", price: "$120",}, {color: "Blue", sizes: "Small", material: "Cotton", price: "$150",}, {color: "Blue", sizes: "Large", material: "Cotton", price: "$180",}, ];
let newVariants = [ {color: "Red", sizes: "Small", material: "Cotton"}, {color: "Red", sizes: "Large", material: "Cotton"}, {color: "Blue", sizes: "Small", material: "Cotton"}, {color: "Blue", sizes: "Large", material: "Wool"}, {color: "Green", sizes: "Large", material: "Cotton"}, ];

const isEqual = (p1, p2) => p1.color == p2.color && p1.sizes == p2.sizes && p1.material == p2.material;
const filteredExtraVariants = newVariants.filter(p1 => !variants.some(p2 => isEqual(p1, p2)));
const extraVariants = filteredExtraVariants.map(r => 
{
  r.price = null;
  return r;
});

const result = variants.concat(extraVariants);
console.log(result);

于 2021-03-08T02:47:17.110 回答
2

我会合并这两个数组,array2 在array1 之前。然后,您可以使用.reduce()构建一个对象(即:一个 Map),该对象由您要合并的值的串联字符串作为键。通过将 array1 放在合并的数组中,其中对象的键/值将覆盖 array2 中的键/值(因此 array1 的对象将优先):

let variants = [ {color: "Red", sizes: "Small", material: "Cotton", price: "$100",}, {color: "Red", sizes: "Large", material: "Cotton", price: "$120",}, {color: "Blue", sizes: "Small", material: "Cotton", price: "$150",}, {color: "Blue", sizes: "Large", material: "Cotton", price: "$180",}, ];
let newVariants = [ {color: "Red", sizes: "Small", material: "Cotton"}, {color: "Red", sizes: "Large", material: "Cotton"}, {color: "Blue", sizes: "Small", material: "Cotton"}, {color: "Blue", sizes: "Large", material: "Wool"}, {color: "Green", sizes: "Large", material: "Cotton"}, ];

const res = Array.from([...newVariants, ...variants].reduce((acc, {price=null, ...rest}) => {
  const key = Object.entries(rest).join("-"); // get a key based on the values (excluding the price)
  return acc.set(key, {...rest, price});
}, new Map).values());

console.log(res);

否则,如果输出数组的顺序很重要,您可以反转数组的合并顺序,并在将其作为值添加到对象中之前检查该值是否已设置:

let variants = [ {color: "Red", sizes: "Small", material: "Cotton", price: "$100",}, {color: "Red", sizes: "Large", material: "Cotton", price: "$120",}, {color: "Blue", sizes: "Small", material: "Cotton", price: "$150",}, {color: "Blue", sizes: "Large", material: "Cotton", price: "$180",}, ];
let newVariants = [ {color: "Red", sizes: "Small", material: "Cotton"}, {color: "Red", sizes: "Large", material: "Cotton"}, {color: "Blue", sizes: "Small", material: "Cotton"}, {color: "Blue", sizes: "Large", material: "Wool"}, {color: "Green", sizes: "Large", material: "Cotton"}, ];

const res = Array.from([...variants, ...newVariants].reduce((acc, {price=null, ...rest}) => {
  const key = Object.entries(rest).join("-"); // get a key based on the values (excluding the price)
  return acc.set(key, acc.get(key) || {...rest, price});
}, new Map).values());

console.log(res);

于 2021-03-08T02:47:17.510 回答
1

你可以做:

const variants = [{ color: "Red", sizes: "Small", material: "Cotton", price: "$100" }, { color: "Red", sizes: "Large", material: "Cotton", price: "$120" }, { color: "Blue", sizes: "Small", material: "Cotton", price: "$150" }, { color: "Blue", sizes: "Large", material: "Cotton", price: "$180" }]
const newVariants = [{ color: "Red", sizes: "Small", material: "Cotton" }, { color: "Red", sizes: "Large", material: "Cotton" }, { color: "Blue", sizes: "Small", material: "Cotton" }, { color: "Blue", sizes: "Large", material: "Wool" }, { color: "Green", sizes: "Large", material: "Cotton" }]

const result = Object.values(
  [...newVariants, ...variants].reduce((a, { color, sizes, material, price = null }) =>
    (a[`${color}-${sizes}-${material}`] = { color, sizes, material, price }, a), {})
)

console.log(result)

于 2021-03-08T03:02:58.680 回答
1

另一种方法是使用.reduce如下:

const variants = [{ color: "Red", sizes: "Small", material: "Cotton", price: "$100" }, { color: "Red", sizes: "Large", material: "Cotton", price: "$120" }, { color: "Blue", sizes: "Small", material: "Cotton", price: "$150" }, { color: "Blue", sizes: "Large", material: "Cotton", price: "$180" }]
const newVariants = [{ color: "Red", sizes: "Small", material: "Cotton" }, { color: "Red", sizes: "Large", material: "Cotton" }, { color: "Blue", sizes: "Small", material: "Cotton" }, { color: "Blue", sizes: "Large", material: "Wool" }, { color: "Green", sizes: "Large", material: "Cotton" }]

const result = [...variants, ...newVariants].reduce((acc, {color, sizes, material, price = null}) => {
   const key = `${color}-${sizes}-${material}`;
   acc[key] ??= {color, sizes, material, price};
   return acc;
  }, {});

console.log(Object.values(result))

于 2021-03-08T03:59:43.767 回答