javascript-如何检查数组中是否存在对象

时间:2018-11-29 23:18:58

标签: javascript

如何检查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);
    }
  });
});

有更好的方法吗?

7 个答案:

答案 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