如何检查JavaScript中数组中是否存在对象?
这是一个简单的例子。假设我有一个看起来像这样的数组:
let array = [{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}]
现在我想将一个对象添加到我的array
中,但前提是该对象尚不存在。
例如,尝试添加该对象将失败:
let addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}]
但这会成功
[{"zone": "SC", "zip": "55555"}, {"zone": "TN", "zip": "88888"}]
显然addMe
是一个数组,需要对某些对象进行故障处理,而对其他对象进行处理。
我正在尝试使用filter
,但无法正常运行。而且我必须遍历原始数组以及遍历我要添加的对象,创建嵌套的for循环,这令人困惑。这是我的尝试:
array.filter(function(item){
addMe.forEach(function(element){
if(item.zone != element.zone && zone.zip!= element.zip){
array.push(element);
}
});
});
有更好的方法吗?
答案 0 :(得分:2)
函数some
可以捕获至少一个every
值不相等的对象。
let array = [{"zone": "WV", "zip": "56855"}, {"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}],
addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
addMe.forEach(o => {
if (!array.some(a => Object.keys(a).every(k => a[k] === o[k]))) array.push(o);
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
使用underscore.js。您可以尝试如下操作:
let array = [
{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}
];
let addMe1 = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
let addMe2 = [{"zone": "SC", "zip": "55555"}, {"zone": "TN", "zip": "88888"}];
// This will fail.
addMe1.forEach( item => !_.findWhere(array, item) ? array.push(item) : null);
// This will success.
addMe2.forEach( item => !_.findWhere(array, item) ? array.push(item) : null);
console.log(array);
<script src="https://fastcdn.org/Underscore.js/1.8.3/underscore-min.js"></script>
答案 2 :(得分:1)
或者,您可以使用JSON.stringify比较两个对象的所有值。
因此,我们首先通过使用filter
在其中比较字符串对象,来some
没有任何重复项。
let array = [{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}]
const newObj = [{"zone": "WV", "zip": "55444"},
{"zone": "SC", "zip": "28031"}]
array = array.concat(newObj.filter(x => !array.some(y => JSON.stringify(y) === JSON.stringify(x))))
console.log(array)
答案 3 :(得分:0)
您可以在ECMAScript 6中使用本机javascript,find()方法:
let array = [{"zone": "WV", "zip": "56855"}, {"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}],
addMe = [{"zone": "SC", "zip": "28031"}, {"zone": "TN", "zip": "84755"}];
addMe.forEach(place => {
if (array.find((element) => element.zone == place.zone) === undefined) {
array.push(place);
}
});
答案 4 :(得分:0)
除了已经给出正确答案外,您的if语句有一个错误(item.zip而不是zone.zip)和对filter
method的误解(返回true表示保留,返回false表示离开)。因此,如果坚持使用滤镜:
let valids = addMe.filter(function(element) {
for(let i=0; i < array.length; i++) {
if(item.zone === element.zone && item.zip === element.zip) return false // throw the item
}
return true; // keep the item
});
array.push(valids);
对于没有过滤器的现代浏览器,使用findIndex的较短方法是:
for(let i = 0; i < addMe.length; i++) {
let index = array.findIndex(item => item.zone === element.zone && item.zip === element.zip);
// will return index of the matching item or -1
if(index < 0) array.push(element); // Add it and you're done
// or better to avoid array search inflation on already added elements
// It will remove element from addMe
addMe.splice(i,1);
}
// In case use of splice
array.push(addMe);
some
方法也是一种处理数组而不是addMe的好方法。
答案 5 :(得分:0)
有一些快速开发,运行缓慢的修复程序,其中涉及每次都搜索所有对象的所有键。或者有一种开发缓慢,运行速度快的解决方案,可以建立某种形式的查找,因此您无需进行所有循环的查找。这是后面的一个简单想法(更多是一个想法的开始)。
创建一个类(或对象),该类保留一组所有已知的键/值对。这只是用分隔符(不应出现在数据中)来连接它们。现在,在添加之前,只需在Set
中进行恒定时间查找即可:
let array = [
{"zone": "WV", "zip": "56855"},
{"zone": "SC", "zip": "28031"},
{"zone": "TN", "zip": "84755"}
]
class unqiueCollection {
constructor(arr, sep = "_"){
this.arr = []
this.sep = sep
this.unique_keys = new Set
arr.forEach((item) => this.add(item))
}
add(item) {
let key = item.zip + '_' + item.zone
if (!this.unique_keys.has(key)) {
this.unique_keys.add(key)
this.arr.push(item)
} else {
console.log("already in array")
}
}
}
let coll = new unqiueCollection(array)
// won't add
coll.add({"zone": "SC", "zip": "28031"})
coll.add({"zip": "28031", "zone": "SC"})
// will add
coll.add({"zone": "AK", "zip": "99577"})
console.log(coll.arr)
这假定所有对象仅由zip和zone组成。如果您的商品更复杂,那么确定组成唯一性的键和逻辑当然也将更复杂。
答案 6 :(得分:-1)
您可以这样做
CultureInfo