Array.push() if does not exist?

JavascriptArraysJsonPushNot Exists

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

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)

Solution 2 - Javascript

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

var arrayObj = [{name:"bull", text: "sour"},
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
]
var index = arrayObj.findIndex(x => x.name=="bob"); 
// here you can check specific property for an object whether it exist in your array or not

index === -1 ? arrayObj.push({your_object}) : console.log("object already exists")
 

Solution 3 - Javascript

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

Solution 4 - Javascript

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

Solution 5 - Javascript

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)

Solution 6 - Javascript

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 }])

Solution 7 - Javascript

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

If the array contains only primitive types/ simple array

var b = [1, 7, 8, 4, 3];
var newItem = 6;
b.indexOf(newItem) === -1 && b.push(newItem);

Solution 8 - Javascript

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]

Solution 9 - Javascript

Easy code, if 'indexOf' returns '-1' it means that element is not inside the array then the condition '=== -1' retrieve true/false.

The '&&' operator means 'and', so if the first condition is true we push it to the array.

array.indexOf(newItem) === -1 && array.push(newItem);

Solution 10 - Javascript

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

Solution 11 - Javascript

My choice was to use .includes() extending the Array.prototype as @Darrin Dimitrov suggested:

Array.prototype.pushIfNotIncluded = function (element) {
    if (!this.includes(element)) {
      this.push(element);
    }
}

Just remembering that includes comes from es6 and does not work on IE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

Solution 12 - Javascript

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

Solution 13 - Javascript

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

Solution 14 - Javascript

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

Solution 15 - Javascript

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

Solution 16 - Javascript

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

Solution 17 - Javascript

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>

Solution 18 - Javascript

a is the array of objects you have

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

Solution 19 - Javascript

Removing duplicates after pushing

If you already have an array containing duplicates, transform the array of objects into an array of strings, and then use the Set() function to eliminate duplicates:

let arr_obj = [
    { name: "tom", text: "tasty" }, 
    { name: "tom", text: "tasty" }
]

let arr_str = arr_obj.map(JSON.stringify)

let arr_unique = [...new Set(arr_str)].map(JSON.parse) 

Checking before pushing

If you don't have duplicates so far and you want to check for duplicates before pushing a new element:

let arr_obj = [
    { name: "tom", text: "tasty" },
    { name: "tim", text: "tusty" }
]

let new_obj = { name: "tom", text: "tasty" }

let arr_str = arr_obj.map(JSON.stringify)

!arr_str.includes(JSON.stringify(new_obj)) && arr_obj.push(new_obj)

Solution 20 - Javascript

Here you have a way to do it in one line for two arrays:

const startArray = [1,2,3,4]
const newArray = [4,5,6]

const result = [...startArray, ...newArray.filter(a => !startArray.includes(a))]

console.log(result);
//Result: [1,2,3,4,5,6]

Solution 21 - Javascript

The question was a litle bit old, but that my option :

    let finalTab = [{id: 1, name: 'dupont'}, {id: 2, name: 'tintin'}, {id: 3, name:'toto'}]; // Your array of object you want to populate with distinct data
    const tabToCompare = [{id: 1, name: 'dupont'}, {id: 4, name: 'tata'}]; // A array with 1 new data and 1 is contain into finalTab
    
    finalTab.push(
      ...tabToCompare.filter(
        tabToC => !finalTab.find(
          finalT => finalT.id === tabToC.id)
      )
    ); // Just filter the first array, and check if data into tabToCompare is not into finalTab, finally push the result of the filters

    console.log(finalTab); // Output : [{id: 1, name: 'dupont'}, {id: 2, name: 'tintin'}, {id: 3, name: 'toto'}, {id: 4, name: 'tata'}];

Solution 22 - Javascript

I would prefer to use native js Array.prototype.some() even in jQ env
Docs: w3s some or mdn some

let arr = [
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
];
let oneMore = { name: "tom", text: "tasty" };
!arr.some(i => i.name == oneMore.name && i.text == oneMore.text)
  && arr.push(oneMore);

Solution 23 - Javascript

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

Solution 24 - Javascript

Short example:

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

Solution 25 - Javascript

someArray = [{a: 'a1 value', b: {c: "c1 value"},
             {a: 'a2 value', b: {c: "c2 value"}]
newObject = {a: 'a2 value', b: {c: "c2 value"}}

//New object which needs check for duplicity

let isExists = checkForExists(newObject) {
    return someArray.some(function(el) {
        return el.a === newObject.a && el.b.c === newObject.b.c;
    });
}
// write your logic here 
// if isExists is true then already object in an array else you can add

Solution 26 - Javascript

I hade this issue and I made a simple prototype, use it if you liked it

Array.prototype.findOrPush = function(predicate, fallbackVal) {
    let item = this.find(predicate)
    if(!item){
        item = fallbackVal
        this.push(item)
    }
    return item
}

let arr = [{id: 1}]
let item = arr.findOrPush(e => e.id == 2, {id: 2})
console.log(item) // {id: 2} 

// will not push and just return existing value
arr.findOrPush(e => e.id == 2, {id: 2}) 
conslog.log(arr)  // [{id: 1}, {id: 2}]

Solution 27 - Javascript

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.

Solution 28 - Javascript

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontarnfeldView Question on Stackoverflow
Solution 1 - JavascriptJiří ZahálkaView Answer on Stackoverflow
Solution 2 - JavascriptAshish YadavView Answer on Stackoverflow
Solution 3 - JavascriptDarin DimitrovView Answer on Stackoverflow
Solution 4 - JavascriptMistereeDevlordView Answer on Stackoverflow
Solution 5 - JavascriptRonnie RoystonView Answer on Stackoverflow
Solution 6 - JavascriptMichael J. ZoidlView Answer on Stackoverflow
Solution 7 - JavascriptGopala raja naikaView Answer on Stackoverflow
Solution 8 - JavascriptRonen RabinoviciView Answer on Stackoverflow
Solution 9 - JavascriptEric ValeroView Answer on Stackoverflow
Solution 10 - JavascriptgiraffesyoView Answer on Stackoverflow
Solution 11 - JavascriptAugusto PeresView Answer on Stackoverflow
Solution 12 - JavascriptmoshefnordView Answer on Stackoverflow
Solution 13 - JavascriptTHE JOATMONView Answer on Stackoverflow
Solution 14 - Javascriptdocta_faustusView Answer on Stackoverflow
Solution 15 - JavascriptVivaLaPandaView Answer on Stackoverflow
Solution 16 - JavascriptSimon HiView Answer on Stackoverflow
Solution 17 - JavascriptTheeCodeDragonView Answer on Stackoverflow
Solution 18 - JavascriptJulio PegueroView Answer on Stackoverflow
Solution 19 - JavascriptErik Martín JordánView Answer on Stackoverflow
Solution 20 - JavascriptJöckerView Answer on Stackoverflow
Solution 21 - JavascriptGoelandManView Answer on Stackoverflow
Solution 22 - JavascriptVasilii SuricovView Answer on Stackoverflow
Solution 23 - Javascriptuser3180914View Answer on Stackoverflow
Solution 24 - JavascriptGigolNftView Answer on Stackoverflow
Solution 25 - Javascriptanil kumar M.VView Answer on Stackoverflow
Solution 26 - JavascriptEboubakerView Answer on Stackoverflow
Solution 27 - JavascriptjgroenenView Answer on Stackoverflow
Solution 28 - JavascriptTaranView Answer on Stackoverflow