gpt4 book ai didi

Javascript:有没有办法防止重复的对象被插入数组?

转载 作者:行者123 更新时间:2023-11-29 10:26:14 26 4
gpt4 key购买 nike

我有多个对象,结构如下:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" }
]
let arr = [];

我正在使用一个循环来迭代 data 并且在每个循环下面都有一个按钮。 单击按钮时,我将对象插入数组,但如果它已经存在,我不希望将其插入数组。有没有办法在不将我的 Array 变成 Set 的情况下做到这一点?

最佳答案

正如上面的各种评论者所指出的,您问​​题的答案在很大程度上取决于您的要求。如果您只需要根据单个属性(例如,name)进行评估,则相对容易:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" },
{ name: "a", position: "A", grade: "" },
{ name: "e", position: "E", grade: "" },
{ name: "c", position: "c", grade: "" }
]
let arr = [];

data.forEach(datum => {
if (!arr.find(item => item.name === datum.name)) {
arr.push(datum);
}
});

console.log(arr);

在这种情况下,如果这是一个可接受的解决方案,您甚至可以想象用普通对象替换数组。然后你可以简单地用 Object.values 获取结果。这个解决方案是 Set-like 而不使用实际的 Set,如果有一些要求阻止它:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" },
{ name: "a", position: "A", grade: "" },
{ name: "e", position: "E", grade: "" },
{ name: "c", position: "c", grade: "" }
]
let dataObject = {};

data.forEach(datum => {
if (!Object.hasOwnProperty(datum.name)) {
dataObject[datum.name] = datum;
}
});

console.log(Object.values(dataObject));

如果评估需要简单地基于指向同一对象的引用发生,使用 Array.prototype.includes 也相对容易:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" },
{ name: "e", position: "E", grade: "" },
];

let data2 = [
data[1],
data[3],
{ name: "f", position: "F", grade: "" },
data[0],
{ name: "g", position: "G", grade: "" },
]

let arr = [];

function pushData(dataArr) {
dataArr.forEach(datum => {
if (!arr.includes(datum)) {
arr.push(datum);
}
})

}

pushData(data);
pushData(data2);

console.log(arr);

唯一开始变得困难的地方是,如果您需要检查等价 对象——具有相同属性值但实际上是不同的不同对象的对象。如果您有一个已知且相对简单的对象形状,您可以为此编写自己的检查。例如,在您的情况下,如果您可以预期只会比较具有 namepositiongrade 属性的对象,那么您可以很容易地编写自定义比较来处理这个问题:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" },
{ name: "a", position: "A", grade: "" },
{ name: "e", position: "E", grade: "" },
{ name: "c", position: "c", grade: "" }
]
let arr = [];

function areDatumsEquivalent(datumA, datumB) {
return (
datumA.name === datumB.name &&
datumA.position === datumB.position &&
datumA.grade === datumB.grade
);
}

data.forEach(datum => {
if(!arr.find(arrDatum => areDatumsEquivalent(datum, arrDatum))) {
arr.push(datum);
}
});

console.log(arr);

但是,如果不是您希望对象具有这种一致性的情况,那么您最好引入一个库来对您的对象进行深入比较(such as lodash isEqual ),或在 Stack Overflow 上寻找人们如何处理自己的解决方案以进行深入比较:

let data = [
{ name: "a", position: "A", grade: "" },
{ name: "b", position: "b", grade: "" },
{ name: "c", position: "c", grade: "" },
{ name: "d", position: "d", grade: "" },
{ name: "a", position: "A", grade: "" },
{ name: "e", position: "E", grade: "" },
{ name: "c", position: "c", grade: "" }
]
let arr = [];

data.forEach(datum => {
if(!arr.find(arrDatum => _.isEqual(datum, arrDatum))) {
arr.push(datum);
}
});

console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

请注意,上述任何利用嵌套循环的解决方案(例如 .forEach.find)随着数组大小的增加而难以扩展。因此,从性能 Angular 来看,使用 Set 或基于对象/哈希的解决方案可能更好。

关于Javascript:有没有办法防止重复的对象被插入数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58617468/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com