120

I have JS array with strings, for example:

var strArray = [ "q", "w", "w", "e", "i", "u", "r"];

I need to compare for duplicate strings inside array, and if duplicate string exists, there should be alert box pointing to that string.

I was trying to compare it with for loop, but I don't know how to write code so that array checks its own strings for duplicates, without already pre-determined string to compare.

4
  • Consecutive duplicates, or duplicates of any sort? If you threw another 'q' in there at the end, should that count as a duplicate or not? Commented Mar 11, 2018 at 0:19
  • Duplicates of any sort. It can be in in the middle of the array, or at the end of the array, or any other combination. Commented Mar 11, 2018 at 0:24
  • In my tests, the fastest method is this one. Commented Aug 29, 2020 at 21:09
  • @ashleedawg in what tests? The array [2,3,4,1,1, ...] where the dots are an array of many elements, should run significantly slower than the hash map as it needs to pass through the full array 4 times in the example above, while a map of values and using in would only go through the array once Commented Jun 13, 2022 at 12:10

13 Answers 13

187

The findDuplicates function (below) compares index of all items in array with index of first occurrence of same item. If indexes are not same returns it as duplicate.

let strArray = [ "q", "w", "w", "w", "e", "i", "i", "u", "r"];
let findDuplicates = arr => arr.filter((item, index) => arr.indexOf(item) !== index)

console.log(findDuplicates(strArray)) // All duplicates
console.log([...new Set(findDuplicates(strArray))]) // Unique duplicates

Sign up to request clarification or add additional context in comments.

2 Comments

Note the time complexity here. Looping inside of a loop: O(n^2). Doesn't really matter unless the array is MASSIVE or you're doing this MANY times on a server. But when it matters, it really matters. kshetline's answer performs better at O(n). BUT, that answer trades time for space (the object map), so watch out for that too :)
This reminds of those old competitions to write the most obfuscated C code possible.
163

Using ES6 features

  • Because each value in the Set has to be unique, the value equality will be checked.

function checkIfDuplicateExists(arr) {
    return new Set(arr).size !== arr.length
}
  
var arr = ["a", "a", "b", "c"];
var arr1 = ["a", "b", "c"];

console.log(checkIfDuplicateExists(arr)); // true
console.log(checkIfDuplicateExists(arr1)); // false

1 Comment

This is the most straight forward and easiest native solution to this day I believe.
34

    var strArray = [ "q", "w", "w", "e", "i", "u", "r", "q"];
    var alreadySeen = {};
  
    strArray.forEach(function(str) {
      if (alreadySeen[str])
        console.log(str);
      else
        alreadySeen[str] = true;
    });

I added another duplicate in there from your original just to show it would find a non-consecutive duplicate.

Updated version with arrow function:

const strArray = [ "q", "w", "w", "e", "i", "u", "r", "q"];
const alreadySeen = {};
  
strArray.forEach(str => alreadySeen[str] ? console.log(str) : alreadySeen[str] = true);

7 Comments

This solution works great, too! Thanks. Shame I can't accept (green checkmark) your answer also.
Nice one. This particular logic easily allows for "Any" behavior (that is, I can short-circuit the loop when I find that there is any duplicate).
Can I clarify something please? Does the above expression alreadySeen[str] = true just add that str item to the alreadySeen array? Is it the same as alreadySeen.push(str)?
@BenClarke, no, because a push word add str as an element of the array, whereas alreadySeen[str] = true adds str as an index of the array, using the array as a hash table. A Set object could be used here instead, perhaps with greater clarity.
@kshetline Ok thank you for clarifying. That's a bit too advanced for me though :) Is that method called anything in particular? I'd like to learn more about it
|
12

You could take a Set and filter to the values that have already been seen.

var array = ["q", "w", "w", "e", "i", "u", "r"],
    seen = array.filter((s => v => s.has(v) || !s.add(v))(new Set));

console.log(seen);

Comments

11

Using some function on arrays: If any item in the array has an index number from the beginning is not equals to index number from the end, then this item exists in the array more than once.

// vanilla js
function hasDuplicates(arr) {
    return arr.some( function(item) {
        return arr.indexOf(item) !== arr.lastIndexOf(item);
    });
}

1 Comment

Hi, your function is what I need (return only a boolean) but I don't know ES6, can you write it in "simple" javascript please ?
2
function hasDuplicateString(strings: string[]): boolean {
    const table: { [key: string]: boolean} = {}
    for (let string of strings) {
        if (string in table) return true;
        table[string] = true;
    }
    return false
}


Here the in operator is generally considered to be an 0(1) time lookup, since it's a hash table lookup.

1 Comment

Yeap this should be the most performant answer
2

Simple Javascript (if you don't know ES6)

function hasDuplicates(arr) {
    var counts = [];

    for (var i = 0; i <= arr.length; i++) {
        if (counts[arr[i]] === undefined) {
            counts[arr[i]] = 1;
        } else {
            return true;
        }
    }
    return false;
}

// [...]

var arr = [1, 1, 2, 3, 4];

if (hasDuplicates(arr)) {
  console.log('Error: you have duplicates values !')
}

Comments

1

var elems = ['f', 'a','b','f', 'c','d','e','f','c'];
elems.sort();

elems.forEach(function (value, index, arr) {
    let first_index = arr.indexOf(value);
    let last_index = arr.lastIndexOf(value);

    if (first_index !== last_index) {
        console.log('Duplicate item in array ' + value);
    } else {
        console.log('unique items in array ' + value);
    }
});

Comments

1

You have to create an empty array then check each element of the given array. If the new array already has the element, log it out. Something like this:

const strArray = ["q", "w", "w", "e", "i", "u", "r"];
let newArray = [];

function check(arr) {
  for (let element of arr) {
    if (newArray.includes(element)) {
      console.log(element)
    } else {
      newArray.push(element);
    }
  }
  return newArray.sort();
}
check(strArray);

Comments

0

Use object keys for good performance when you work with a big array (in that case, loop for each element and loop again to check duplicate will be very slowly).

var strArray = ["q", "w", "w", "e", "i", "u", "r"];

var counting = {};
strArray.forEach(function (str) {
    counting[str] = (counting[str] || 0) + 1;
});

if (Object.keys(counting).length !== strArray.length) {
    console.log("Has duplicates");

    var str;
    for (str in counting) {
        if (counting.hasOwnProperty(str)) {
            if (counting[str] > 1) {
                console.log(str + " appears " + counting[str] + " times");
            }
        }
    }
}

Comments

0

This is the simplest solution I guess :

function diffArray(arr1, arr2) {
  return arr1
    .concat(arr2)
    .filter(item => !arr1.includes(item) || !arr2.includes(item));
}

Comments

0
 const isDuplicate = (str) =>{
   return new Set(str.split("")).size === str.length;
}

2 Comments

Can you explain why this works? Since this question is rather old, it's a good idea to clearly articulate why it is useful.
The above method is a predicate method which means is only returning boolean value. Since set take only unique value, I split the string to array of character then I parse the array of character to the set constructor for removing any duplicate character. Which mean if duplicate exist in the character array, the set will contain on the unique ones, after that I compare the length of the original string against the set size. If the length are the same it means no duplicate else it means there is.
-1

You could use reduce:

const arr = ["q", "w", "w", "e", "i", "u", "r"]
arr.reduce((acc, cur) => { 
  if(acc[cur]) {
    acc.duplicates.push(cur)
  } else {
    acc[cur] = true //anything could go here
  }
}, { duplicates: [] })

Result would look like this:

{ ...Non Duplicate Values, duplicates: ["w"] }

That way you can do whatever you want with the duplicate values!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.