如何避免在列表中添加重复对象

时间:2017-07-26 03:49:15

标签: javascript angular

这是我的模特课

export class PersonModel {

    persCode:number;
    name:string;
    contactNumber:number;
    remarks:string;
  }

我有一个PersonModel对象列表

   affectedPersons: PersonModel[] = [];

如何检查此列表中是否存在对象。这样我就可以避免添加重复值。

addVisitor() {
        let visitorVal : PersonModel ;
        visitorVal = this.affectedPersons.filter(x => x.name == this.visitorName && x.contactNumber== this.visitorMob && x.remarks==this.visitorRemark, x => console.log("x "+ JSON.stringify(x)))
            .map(x => x)[0];

        }

这不起作用。我怎样才能实现这个目标

1 个答案:

答案 0 :(得分:1)

以JS函数的形式定义“相等”的概念。这就是它们的用途。

function objectsAreEqual(obj1, obj2) {
  return obj1.name === obj2.visitorName &&
    obj1.contactNumber === obj2.visitorMob &&
    obj1.remarks === objs.visitorRemark;
}

现在,您可以通过

查找对象是否在对象数组中
const visitorAlreadyInArray = arr.some(obj => objectsAreEqual(obj, newObj))

如果要查找实际的匹配对象,则

const visitorVal = arr.find(obj => objectsAreEqual(obj, newObj))

filter可以在这种情况下工作,但它不是最好的解决方案。从逻辑上讲,过滤器旨在缩小范围。那不是你想要做的。你正试图找到一件事。这就是find的用途。它的优点是一旦找到它正在寻找的东西它就会停止。在合同中,filter将继续在数组的所有元素上运行,即使它已经找到了第一个匹配项。

但是,这不是一个理想的解决方案。您已将对象属性的名称硬连接到解决方案中。这意味着每次更改或添加属性时,您都必须更改此部分代码。这不是一件好事。我们想要编写一个更好的版本,无论属性是什么,都可以使用。

为此,您首先需要切换到一致的属性命名。不是为数组中的对象的属性使用一个名称(name),而是为要匹配的对象(visitorName)的属性使用另一个不同的名称,请为两者使用相同的名称(name)。

现在我们可以编写一个比较任意两个对象的函数,以确保它们的所有属性都相同。这是一个老问题。您必须决定是否要以嵌套方式比较这两个对象(如果它们包含子对象)。 Here is a thread on this topic。如果你想进行“浅层”比较,那么你可以做类似的事情:

function compareObjects(obj1, obj2) {
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Object.keyw(obj2);

  return obj1Keys.length === obj2Keys.length &&
    obj1Keys.every(key => obj1[key] === obj2[key]);
}

现在我可以通过说

来使用它来查找数组中的匹配对象
arr.find(obj => compareObjects(obj, newObj))

这将检查所有属性是否相同。如果你想要检查属性的某个子集是否是更改,你必须通过传入要检查的属性列表以某种方式调整它。

请注意,这些都与TypeScript或Angular无关。这是纯粹的JavaScript。但是,使用TypeScript,您可以通过坚持两个输入都是对象和相同类型来以更加类型安全的方式编写compareObjects函数:

function compareObjects<T extends object>(obj1: T, obj2: T) {
  const obj1Keys = Object.keys(obj1);
  const obj2Keys = Object.keyw(obj2);

  return obj1Keys.length === obj2Keys.length &&
    obj1Keys.every(key => obj1[key] === obj2[key]);
}

现在,如果您尝试传入两个不兼容的对象进行比较,编译器会抱怨。