50

I found a lot of related questions with answers talking about for...in loops and using hasOwnProperty but nothing I do works properly. All I want to do is check whether or not a key exists in an array and if not, add it.

I start with an empty array then add keys as the page is scrubbed with jQuery.

Initially, I hoped that something simple like the following would work: (using generic names)

if (!array[key])
   array[key] = value;

No go. Followed it up with:

for (var in array) {
   if (!array.hasOwnProperty(var))
      array[key] = value;
}

Also tried:

if (array.hasOwnProperty(key) == false)
   array[key] = value;

None of this has worked. Either nothing is pushed to the array or what I try is no better than simply declaring array[key] = value Why is something so simple so difficult to do. Any ideas to make this work?

iamsar
  • 1,080
  • 2
  • 15
  • 28

8 Answers8

48

Generally speaking, this is better accomplished with an object instead since JavaScript doesn't really have associative arrays:

var foo = { bar: 0 };

Then use in to check for a key:

if ( !( 'bar' in foo ) ) {
    foo['bar'] = 42;
}

As was rightly pointed out in the comments below, this method is useful only when your keys will be strings, or items that can be represented as strings (such as numbers).

Sampson
  • 265,109
  • 74
  • 539
  • 565
  • 2
    ...assuming that your values are strings or representable as unique strings (this includes numbers). – Phrogz May 25 '12 at 15:52
  • 1
    @Phrogz Absolutely. Good bit of advice to the OP. – Sampson May 25 '12 at 16:00
  • 3
    Thanks Jonathan. The light FINALLY clicked as to what I was doing wrong. I was about to say your answer didn't help either but after a little more detective work, I'm pleased to say it worked perfectly. And thanks for the tips on Objects. I'll keep that in mind down the road. – iamsar May 26 '12 at 02:26
42
var a = [1,2,3], b = [4,1,5,2];

b.forEach(function(value){
  if (a.indexOf(value)==-1) a.push(value);
});

console.log(a);
// [1, 2, 3, 4, 5]

For more details read up on Array.indexOf.

If you want to rely on jQuery, instead use jQuery.inArray:

$.each(b,function(value){
  if ($.inArray(value,a)==-1) a.push(value);
});

If all your values are simply and uniquely representable as strings, however, you should use an Object instead of an Array, for a potentially massive speed increase (as described in the answer by @JonathanSampson).

Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 2
    Also, the problem with using `indexOf` is that it itself makes a loop... This makes for a [Schlemiel the painter's algorithm](http://en.wikichip.org/wiki/Schlemiel_the_Painter's_Algorithm) that slows down with every item added to the array. – Stijn de Witt Sep 22 '15 at 22:29
23

A better alternative is provided in ES6 using Sets. So, instead of declaring Arrays, it is recommended to use Sets if you need to have an array that shouldn't add duplicates.

var array = new Set();
array.add(1);
array.add(2);
array.add(3);

console.log(array);
// Prints: Set(3) {1, 2, 3}

array.add(2); // does not add any new element

console.log(array);
// Still Prints: Set(3) {1, 2, 3}
Pavan
  • 632
  • 5
  • 9
  • 2
    Only works with primitive types, so sets are really limited. – Erik Philips Jun 11 '19 at 22:09
  • 5
    @Erik: According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set: The Set object lets you store **unique values of any type, whether primitive values or object references**. – VanagaS Jul 18 '19 at 04:19
  • 3
    It accepts any values, but is not able to evaluate equality for non-primitives. http://jsfiddle.net/poLd7tk6/ – gunwin Jan 28 '21 at 22:05
  • from what I see, set returns an object not an array – Okiemute Gold Dec 16 '22 at 06:42
5

Here's a simple way using spread.

This code will give duplicates:

let colors = ['red', 'orange', 'yellow'];
let moreColors = ['orange', 'green'];

// uh oh! this gives us 'orange' twice
let mergedColors = [...colors, ...moreColors];

So you can filter and remove them at the same time you merge the arrays.

let mergedColors = [...colors, ...moreColors.filter(c => !colors.includes(c)) ];
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
1

You can try this:

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});

Easiest way to find duplicate values in a JavaScript array

Community
  • 1
  • 1
Bruno Pinna
  • 123
  • 11
0

The logic is wrong. Consider this:

x = ["a","b","c"]
x[0]     // "a"
x["0"]   // "a"
0 in x   // true
"0" in x // true
x.hasOwnProperty(0)   // true
x.hasOwnProperty("0") // true

There is no reason to loop to check for key (or indices for arrays) existence. Now, values are a different story...

Happy coding

0
function check (list){
    var foundRepeatingValue = false;
    var newList = [];
    for(i=0;i<list.length;i++){
        var thisValue = list[i];
        if(i>0){
            if(newList.indexOf(thisValue)>-1){
                foundRepeatingValue = true;
                console.log("getting repeated");
                return true;
            }
       } newList.push(thisValue);
    } return false;
}

 

var list1 = ["dse","dfg","dse"];
check(list1);

Output:

getting repeated
true
VLS
  • 2,306
  • 4
  • 22
  • 17
abhiagNitk
  • 1,047
  • 10
  • 19
-1

let x = "farceus";
let y = "character";

const commonCharacters = function (string1, string2) {
  let duplicateCharacter = "";
  for (let i = 0; i < string1.length; i += 1) {
    if (duplicateCharacter.indexOf(string1[i]) === -1) {
      if (string2.indexOf(string1[i]) !== -1) {
        duplicateCharacter += string1[i];
      }
    }
  }
  return [...duplicateCharacter];
};


console.log(commonCharacters(x, y));
devXd
  • 177
  • 3
  • 4