Array.push() if does not exist?

寵の児 提交于 2019-12-17 02:07:50

问题


How can I push into an array if neither values exist? Here is my array:

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

If I tried to push again into the array with either name: "tom" or text: "tasty", I don't want anything to happen... but if neither of those are there then I want it to .push()

How can I do this?


回答1:


You could extend the Array prototype with a custom method:

// 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; 
});



回答2:


For an array of strings (but not an array of objects), you can check if an item exists by calling .indexOf() and if it doesn't then just push the item into the array:

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");

console.log(array)



回答3:


It is quite easy to do using the Array.findIndex function, which takes a function as an argument:

var a = [{name:"bull", text: "sour"},
    { 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")



回答4:


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

var cleanArray = $.unique(clutteredArray);

you might be interested in makeArray too

The previous example is best in saying that check if it exists before pushing. I see in hindsight it also states you can declare it as part of the prototype (I guess that's aka Class Extension), so no big enhancement below.

Except I'm not sure if indexOf is a faster route then inArray? probably.

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



回答5:


Use a js library like underscore.js for these reasons exactly. Use: union: Computes the union of the passed-in arrays: the list of unique items, in order, that are present in one or more of the arrays.

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



回答6:


Like this?

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

With object

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



回答7:


I know this is a very old question, but if you're using ES6 you can use a very small version:

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

Very easy, at first add a filter which removes the item - if it already exists, and then add it via a concat.

Here is a more realistic example:

const myArray = ['hello', 'world']
const newArrayItem

myArray.filter(f => f !== newArrayItem).concat([newArrayItem])

If you're array contains objects you could adapt the filter function like this:

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



回答8:


Push dynamically

var a = [
  {name:"bull", text: "sour"},
  {name: "tom", text: "tasty" },
  {name: "Jerry", text: "tasty" }
]

function addItem(item) {
  var index = a.findIndex(x => x.name == item.name)
  if (index === -1) {
    a.push(item);
  }else {
    console.log("object already exists")
  }
}

var item = {name:"bull", text: "sour"};
addItem(item);

In simple method

var item = {name:"bull", text: "sour"};
a.findIndex(x => x.name == item.name) == -1 ? a.push(item) : console.log("object already exists")



回答9:


I would suggest you use a Set,

Sets only allow unique entries, which automatically solves your problem.

Sets can be declared like so:

const baz = new Set(["Foo","Bar"])



回答10:


Not sure about speed, but stringification + indexOf is a simple approach. Start with turning your array into a string:

let strMyArray = JSON.stringify(myArray);

Then for a series of attribute-value pairs you can use:

if (strMyArray.indexOf('"name":"tom"') === -1 && strMyArray.indexOf('"text":"tasty"') === -1) {
   myArray.push({ name: "tom", text: "tasty" });
}

Finding a whole object is simpler:

if (strMyArray.indexOf(JSON.stringify(objAddMe) === -1) { 
   myArray.push(objAddMe);
}



回答11:


In case you need something simple without wanting to extend the Array prototype:

// 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);
}



回答12:


In case anyone has less complicated requirements, here is my adaptation of the answer for a simple string array:

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

Update: Replaced indexOf and trim with jQuery alternatives for IE8 compatability




回答13:


I used map and reduce to do this in the case where you wish to search by the a specific property of an object, useful as doing direct object equality will often fail.

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");
}



回答14:


Short example:

if (typeof(arr[key]) === "undefined") {
  arr.push(key);
}



回答15:


a is the array of objects you have

a.findIndex(x => x.property=="WhateverPropertyYouWantToMatch") <0 ? 
a.push(objectYouWantToPush) : console.log("response if object exists");



回答16:


You can use the findIndex method with a callback function and its "this" parameter.

Note: old browsers don't know findIndex but a polyfill is available.

Sample code (take care that in the original question, a new object is pushed only if neither of its data is in previoulsy pushed objects):

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



回答17:


I guess i am too late to answer here however this is what i finally came up with for a mail manager i wrote. Works that's all i need.

window.ListManager = [];
$('#add').click(function(){
//Your Functionality
  let data =Math.floor(Math.random() * 5) + 1 
  
  if (window.ListManager.includes(data)){
      console.log("data exists in list")
  }else{
       window.ListManager.push(data);
  }
  
  
  $('#result').text(window.ListManager);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Unique List</h1>

<p id="result"></p>
<button id="add">Add to List</button>



回答18:


This is working func for an objects comparison. In some cases you might have lot of fields to compare. Simply loop the array and call this function with a existing items and new item.

 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;
    };



回答19:


You can use jQuery grep and push if no results: http://api.jquery.com/jQuery.grep/

It's basically the same solution as in the "extending the prototype" solution, but without extending (or polluting) the prototype.




回答20:


You can check the array using foreach and then pop the item if it exists otherwise add new item...

sample newItemValue &submitFields are key,value pairs

> //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});


来源:https://stackoverflow.com/questions/1988349/array-push-if-does-not-exist

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!