Array.push()如果不存在?

如果两个值都不存在,我怎样才能把数组推进? 这是我的数组:

[ { name: "tom", text: "tasty" }, { name: "tom", text: "tasty" }, { name: "tom", text: "tasty" }, { name: "tom", text: "tasty" }, { name: "tom", text: "tasty" } ] 

如果我尝试再次推入数组中, name: "tom"text: "tasty" ,我不想要发生任何事情……但如果这两者都不存在,那么我希望它可以.push()

我该怎么做?

您可以使用自定义方法扩展数组原型:

 // check if an element exists in array using a comparer function // comparer : function(currentElement) Array.prototype.inArray = function(comparer) { for(var i=0; i < this.length; i++) { if(comparer(this[i])) return true; } return false; }; // adds an element to the array if it does not already exist using a comparer // function Array.prototype.pushIfNotExist = function(element, comparer) { if (!this.inArray(comparer)) { this.push(element); } }; var array = [{ name: "tom", text: "tasty" }]; var element = { name: "tom", text: "tasty" }; array.pushIfNotExist(element, function(e) { return e.name === element.name && e.text === element.text; }); 

对于一个string数组(但不是一个对象数组),你可以通过调用.indexOf()来检查一个项是否存在,如果不存在,那么只需该项放入数组中:

 var newItem = "NEW_ITEM_TO_ARRAY"; var array = ["OLD_ITEM_1", "OLD_ITEM_2"]; array.indexOf(newItem) === -1 ? array.push(newItem) : console.log("This item already exists"); 

http://api.jquery.com/jQuery.unique/

 var cleanArray = $.unique(clutteredArray); 

你也可能对makeArray感兴趣

前面的例子最好是在推之前检查它是否存在。 事后看来,它也声明你可以声明它是原型的一部分(我猜这也是类扩展),所以下面没有大的改进。

除了我不确定是否indexOf是一个更快的路线,然后inArray? 大概。

 Array.prototype.pushUnique = function (item){ if(this.indexOf(item) == -1) { //if(jQuery.inArray(item, this) == -1) { this.push(item); return true; } return false; } 

正是由于这些原因才使用像underscore.js这样的js库。 使用:union:计算传入数组的联合:唯一项的列表,按顺序存在于一个或多个数组中。

 _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2, 3, 101, 10] 

使用Array.findIndex函数很容易,它将一个函数作为参数:

 var a = [{name:"bull"}, { name: "tom", text: "tasty" }, { name: "tom", text: "tasty" } ] var index = a.findIndex(x => x.name=="bob") // here you can check specific property for an object whether it exist in your array or not if (index === -1){ a.push({your_object}); } else console.log("object already exists") 

喜欢这个?

 var item = "Hello World"; var array = []; if (array.indexOf(item) === -1) array.push(item); 

与对象

 var item = {name: "tom", text: "tasty"} var array = [{}] if (!array.find(o => o.name === 'tom' && o.text === 'tasty')) array.push(item) 

如果你需要简单的东西而不想扩展数组原型:

 // Example array var array = [{id: 1}, {id: 2}, {id: 3}]; function pushIfNew(obj) { for (var i = 0; i < array.length; i++) { if (array[i].id === obj.id) { // modify whatever property you need return; } } array.push(obj); } 

如果任何人有更简单的要求,这里是我对一个简单的string数组的答案:

 Array.prototype.pushIfNotExist = function(val) { if (typeof(val) == 'undefined' || val == '') { return; } val = $.trim(val); if ($.inArray(val, this) == -1) { this.push(val); } }; 

更新:replaceindexOf和修剪与jQuery替代IE8兼容性

我使用map和reduce来做这件事情,你希望通过对象的特定属性进行search,这很有用,因为做直接的对象平等往往会失败。

 var newItem = {'unique_id': 123}; var searchList = [{'unique_id' : 123}, {'unique_id' : 456}]; hasDuplicate = searchList .map(function(e){return e.unique_id== newItem.unique_id}) .reduce(function(pre, cur) {return pre || cur}); if (hasDuplicate) { searchList.push(newItem); } else { console.log("Duplicate Item"); } 

您可以将findIndex方法与callback函数及其“this”参数一起使用。

注意:旧的浏览器不知道findIndex,但可以使用polyfill。

示例代码(请注意,在原始问题中,只有当其中的数据都不在先前推送的对象中时才会推送新的对象):

 var a=[{name:"tom", text:"tasty"}], b; var magic=function(e) { return ((e.name == this.name) || (e.text == this.text)); }; b={name:"tom", text:"tasty"}; if (a.findIndex(magic,b) == -1) a.push(b); // nothing done b={name:"tom", text:"ugly"}; if (a.findIndex(magic,b) == -1) a.push(b); // nothing done b={name:"bob", text:"tasty"}; if (a.findIndex(magic,b) == -1) a.push(b); // nothing done b={name:"bob", text:"ugly"}; if (a.findIndex(magic,b) == -1) a.push(b); // b is pushed into a 

如果没有结果,你可以使用jQuery grep和push: http : //api.jquery.com/jQuery.grep/

这与“扩展原型”解决scheme基本相同,但不扩展(或污染)原型。

您可以使用foreach检查数组,如果存在,则popup该项目,否则添加新项目…

示例newItemValue&submitFields是键值对

 > //submitFields existing array > angular.forEach(submitFields, function(item) { > index++; //newItemValue new key,value to check > if (newItemValue == item.value) { > submitFields.splice(index-1,1); > > } }); submitFields.push({"field":field,"value":value}); 

我知道这是一个非常古老的问题,但如果你使用ES6,你可以使用一个非常小的版本:

 [1,2,3].filter(f => f !== 3).concat([3]) 

非常容易,首先添加一个filter,删除项目 – 如果它已经存在,然后通过concat添加它。

这是一个更现实的例子:

 const myArray = ['hello', 'world'] const newArrayItem myArray.filter(f => f !== newArrayItem).concat([newArrayItem]) 

如果你的数组包含对象,你可以像这样调整filter函数:

 someArray.filter(f => f.some(s => s.id === myId)).concat([{ id: myId }]) 

这是工作func对象比较。 在某些情况下,您可能需要很多字段进行比较。 简单地循环数组,并用现有的项目和新项目调用此函数。

  var objectsEqual = function (object1, object2) { if(!object1 || !object2) return false; var result = true; var arrayObj1 = _.keys(object1); var currentKey = ""; for (var i = 0; i < arrayObj1.length; i++) { currentKey = arrayObj1[i]; if (object1[currentKey] !== null && object2[currentKey] !== null) if (!_.has(object2, currentKey) || !_.isEqual(object1[currentKey].toUpperCase(), object2[currentKey].toUpperCase())) return false; } return result; };