【问题标题】:How to compere 2 arrays of objects and get the changed array object如何完成 2 个对象数组并获取更改后的数组对象
【发布时间】:2021-11-30 03:58:57
【问题描述】:

我有 2 个对象数组。一个是旧数组,另一个是新数组。当比较旧数组和新数组时,我想要的输出是一个包含任何属性已更改的所有元素的数组。它应该适用于对象可能具有的任何属性,而不限于给定的 3。不过,你不需要处理嵌套对象。

let old = [
    {
      id: "f4101804-a587-4420-97d3-5691a93c9143",
      name: "Mice",
      price: "25"
    },
    {
      id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
      name: "acooer",
      price: "25"
    },
    {
      id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
      name: "Yhgg",
      price: "25"
    },
    {
      id: "01381e2c-ee25-4461-93cb-d54c812551e9",
      name: "anix",
      price: "25"
    }
  ];

  let new = [
    {
      id: "f4101804-a587-4420-97d3-5691a93c9143",
      name: "Mice",
      price: "25"
    },
    {
      id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
      name: "acoo",
      price: "25"
    },
    {
      id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
      name: "Yhgg",
      price: "26"
    },
    {
      id: "01381e2c-ee25-4461-93cb-d54c812551e9",
      name: "anix",
      price: "25"
    }
  ];

在给定的示例中,第二个元素的 name 属性和第三个元素的 price 属性已更改。所以输出应该是

[
  {
    id: '132a5f3b-7350-44e6-8ac8-3ba1b558ff1c',
    name: 'acoo',
    price: '25'
  },
  {
    id: 'b1cf9e9d-e712-4624-b754-fb9c48a75716',
    name: 'Yhgg',
    price: '26'
  }
]

我试过这个,但是当我改变对象的位置时,它被认为是对象的变化。

import "./styles.css";

const a = [
  {
    id: "f4101804-a587-4420-97d3-5691a93c9143",
    name: "Mice",
    price: "25"
  },
  {
    id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
    name: "acooer",
    price: "25"
  },
  {
    id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
    name: "Yhgg",
    price: "25"
  },
  {
    id: "01381e2c-ee25-4461-93cb-d54c812551e9",
    name: "anix",
    price: "25"
  }
];
const b = [
  {
    id: "f4101804-a587-4420-97d3-5691a93c9143",
    name: "Mice",
    price: "25"
  },
  {
    id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
    name: "acoo",
    price: "25"
  },
  {
    id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
    name: "Yhgg",
    price: "26"
  },
  {
    id: "01381e2c-ee25-4461-93cb-d54c812551e9",
    name: "anixx",
    price: "25"
  }
];
let result = b.filter(
  (elm) => !a.map((elm) => JSON.stringify(elm)).includes(JSON.stringify(elm))
);
console.log(result);

document.getElementById("app").innerHTML = JSON.stringify(result, null, 2);

【问题讨论】:

  • 在 SO 上,习惯上是在您编写的代码上寻求帮助,而不是在编写代码时寻求帮助。请编辑问题以显示尝试的解决方案。
  • 我几乎编写了所有代码。但是当我改变物体的位置时,它被认为是物体的变化。解决方案在链接中查看

标签: arrays arrayobject


【解决方案1】:

OP 的过滤谓词有一些错误,包括使用相同的虚拟参数 elm(隐藏过滤器的参数),以及测试返回数组而不是 findmap

这是一个改进的谓词:

let result = b.filter(bElement => {
  return !a.find(aElement => isEquivalent(aElement, bElement))
});

注意几点:

  • 虚拟参数的命名与它们来自的数组相匹配
  • return !a.find 对找到的东西返回 false,否则返回 true
  • 等价性已被分解,因此可以作为自己的问题处理

OP 尝试使用常见的等价测试,比较字符串表示,是否为JSON.stringify(someObjectA) === JSON.stringify(someObjectB),但这种方法有缺点。

一个是必须在进行任何比较之前构建两个字符串。如果对象很大,但每个键都不同怎么办?这可以在创建(然后丢弃)两个大字符串之前进行测试。

另一个缺点与 JS 的不同实现可能在 stringify 中产生不同的键顺序有关。虽然大多数实现产生相同的字符串,但语言不保证键顺序(据我所知)。

下面的 sn-p 包含两个等价替代方案:isEquivalent_0() 使用了不明智的 stringify 测试。 isEquivalent_1() 对值进行了浅层测试。一旦发现键或值不匹配,它就会退出,并且不会创建中间(垃圾)对象。

const a = aData();
const b = bData();

// this equivalence compares string representation of objects
function isEquivalent_0(objA, objB) {
  return JSON.stringify(objA) === JSON.stringify(objB)
}

// this shallow equivalence checks keys and values, and terminates
// as soon as a mismatch is found
function isEquivalent_1(objA, objB) {
  for (aKey in objA) {
    if (!(aKey in objB)) return false;
    if (objA[aKey] !== objB[aKey]) return false;
  }
  for (bKey in objB) {
    if (!(bKey in objA)) return false;
    if (objA[aKey] !== objB[aKey]) return false;
  }
  return true;
}

let result = b.filter(bElement => {
  return !a.find(aElement => isEquivalent_1(aElement, bElement))
});

console.log(result);

function aData() {
  return [{
      id: "f4101804-a587-4420-97d3-5691a93c9143",
      name: "Mice",
      price: "25"
    },
    {
      id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
      name: "acooer",
      price: "25"
    },
    {
      id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
      name: "Yhgg",
      price: "25"
    },
    {
      id: "01381e2c-ee25-4461-93cb-d54c812551e9",
      name: "anix",
      price: "25"
    }
  ];
}

function bData() {
  return [{
      id: "f4101804-a587-4420-97d3-5691a93c9143",
      name: "Mice",
      price: "25"
    },
    {
      id: "132a5f3b-7350-44e6-8ac8-3ba1b558ff1c",
      name: "acoo",
      price: "25"
    },
    {
      id: "b1cf9e9d-e712-4624-b754-fb9c48a75716",
      name: "Yhgg",
      price: "26"
    },
    {
      id: "01381e2c-ee25-4461-93cb-d54c812551e9",
      name: "anix",
      price: "25"
    }
  ];
}

【讨论】:

    猜你喜欢
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2011-11-01
    • 2019-07-04
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多