I need to check a JavaScript array to see if there are any duplicate values. What's the easiest way to do this? I just need to find what the duplicated values are - I don't actually need their indexes or how many times they are duplicated.
I know I can loop through the array and check all the other values for a match, but it seems like there should be an easier way.
This question is related to
javascript
arrays
This can also be solved using Set()
.
A value in the Set may only occur once; it is unique in the Set's collection.
Array.prototype.hasDuplicates = function () {
if (arr.length !== (new Set(arr).size)) {
return true;
}
return false;
}
More information on Sets: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
Note: Sets are not fully supported in IE.
var arr = [4,5,1,1,2,3,4,4,7,5,2,6,10,9];_x000D_
var sorted_arr = arr.sort();_x000D_
var len = arr.length;_x000D_
var results = [];_x000D_
for (var i = 0; i < len; i++) {_x000D_
if (sorted_arr[i + 1] !== sorted_arr[i]) {_x000D_
results.push(sorted_arr[i]);_x000D_
}_x000D_
}_x000D_
document.write(results);
_x000D_
Just to add some theory to the above.
Finding duplicates has a lower bound of O(n*log(n) in the comparison model. SO theoretically, you cannot do any better than first sorting then going through the list sequentially removing any duplicates you find.
If you want to find the duplicates in linear (O(n)) expected time, you could hash each element of the list; if there is a collision, remove/label it as a duplicate, and continue.
ES5 only (i.e., it needs a filter() polyfill for IE8 and below):
var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];
arrayToFilter.
sort().
filter( function(me,i,arr){
return (i===0) || ( me !== arr[i-1] );
});
This is my proposal (ES6):
let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]
// b is now [1, 2, 4]
Simplest way to fetch duplicates/repeated values from array/string :
function getDuplicates(param) {_x000D_
var duplicates = {}_x000D_
_x000D_
for (var i = 0; i < param.length; i++) {_x000D_
var char = param[i]_x000D_
if (duplicates[char]) {_x000D_
duplicates[char]++_x000D_
} else {_x000D_
duplicates[char] = 1_x000D_
}_x000D_
}_x000D_
return duplicates_x000D_
}_x000D_
_x000D_
console.log(getDuplicates("aeiouaeiou"));_x000D_
console.log(getDuplicates(["a", "e", "i", "o", "u", "a", "e"]));_x000D_
console.log(getDuplicates([1, 2, 3, 4, 5, 1, 1, 2, 3]));
_x000D_
http://jsfiddle.net/vol7ron/gfJ28/
var arr = ['hello','goodbye','foo','hello','foo','bar',1,2,3,4,5,6,7,8,9,0,1,2,3];
var hash = [];
// build hash
for (var n=arr.length; n--; ){
if (typeof hash[arr[n]] === 'undefined') hash[arr[n]] = [];
hash[arr[n]].push(n);
}
// work with compiled hash (not necessary)
var duplicates = [];
for (var key in hash){
if (hash.hasOwnProperty(key) && hash[key].length > 1){
duplicates.push(key);
}
}
alert(duplicates);
The result will be the hash
array, which will contain both a unique set of values and the position of those values. So if there are 2 or more positions, we can determine that the value has a duplicate. Thus, every place hash[<value>].length > 1
, signifies a duplicate.
hash['hello']
will return [0,3]
because 'hello' was found in node 0 and 3 in arr[]
.
Note: the length of [0,3]
is what's used to determine if it was a duplicate.
Using for(var key in hash){ if (hash.hasOwnProperty(key)){ alert(key); } }
will alert each unique value.
var a= [1, 2,2,3,3,4,4,4];
var m=[];
var n = [];
a.forEach(function(e) {
if(m.indexOf(e)=== -1) {
m.push(e);
}else if(n.indexOf(e)=== -1){
n.push(e);
}
});
UPDATED: The following uses an optimized combined strategy. It optimizes primitive lookups to benefit from hash O(1) lookup time (running unique
on an array of primitives is O(n)). Object lookups are optimized by tagging objects with a unique id while iterating through so so identifying duplicate objects is also O(1) per item and O(n) for the whole list. The only exception is items that are frozen, but those are rare and a fallback is provided using an array and indexOf.
var unique = function(){
var hasOwn = {}.hasOwnProperty,
toString = {}.toString,
uids = {};
function uid(){
var key = Math.random().toString(36).slice(2);
return key in uids ? uid() : uids[key] = key;
}
function unique(array){
var strings = {}, numbers = {}, others = {},
tagged = [], failed = [],
count = 0, i = array.length,
item, type;
var id = uid();
while (i--) {
item = array[i];
type = typeof item;
if (item == null || type !== 'object' && type !== 'function') {
// primitive
switch (type) {
case 'string': strings[item] = true; break;
case 'number': numbers[item] = true; break;
default: others[item] = item; break;
}
} else {
// object
if (!hasOwn.call(item, id)) {
try {
item[id] = true;
tagged[count++] = item;
} catch (e){
if (failed.indexOf(item) === -1)
failed[failed.length] = item;
}
}
}
}
// remove the tags
while (count--)
delete tagged[count][id];
tagged = tagged.concat(failed);
count = tagged.length;
// append primitives to results
for (i in strings)
if (hasOwn.call(strings, i))
tagged[count++] = i;
for (i in numbers)
if (hasOwn.call(numbers, i))
tagged[count++] = +i;
for (i in others)
if (hasOwn.call(others, i))
tagged[count++] = others[i];
return tagged;
}
return unique;
}();
If you have ES6 Collections available, then there is a much simpler and significantly faster version. (shim for IE9+ and other browsers here: https://github.com/Benvie/ES6-Harmony-Collections-Shim)
function unique(array){
var seen = new Set;
return array.filter(function(item){
if (!seen.has(item)) {
seen.add(item);
return true;
}
});
}
You can use the following construction:
var arr = [1,2,3,4,5,6,7,8,9,0,5];
var duplicate = arr.filter(function(item, i, arr) {
return -1 !== arr.indexOf(item, i + 1);
})
/* The indexOf method of the Array object is useful for comparing array items. IE is the only major browser that does not natively support it, but it is easy to implement: */
Array.prototype.indexOf= Array.prototype.indexOf || function(what, i){
i= i || 0;
var L= this.length;
while(i<L){
if(this[i]=== what) return i;
++i;
}
return -1;
}
function getarrayduplicates(arg){
var itm, A= arg.slice(0, arg.length), dups= [];
while(A.length){
itm= A.shift();
if(A.indexOf(itm)!= -1 && dups.indexOf(itm)== -1){
dups[dups.length]= itm;
}
}
return dups;
}
var a1= [1, 22, 3, 2, 2, 3, 3, 4, 1, 22, 7, 8, 9];
alert(getarrayduplicates(a1));
For very large arrays, it can be faster to remove the duplicates from the array as they are found, so that they will not be looked at again:
function getarrayduplicates(arg){
var itm, A= arg.slice(0, arg.length), dups= [];
while(A.length){
itm= A.shift();
if(A.indexOf(itm)!= -1){
dups[dups.length]= itm;
while(A.indexOf(itm)!= -1){
A.splice(A.indexOf(itm), 1);
}
}
}
return dups;
}
This is more advanced function based on number of occurences.
function getMostDuplicated(arr, count) {
const result = [];
arr.forEach((item) => {
let i = 0;
arr.forEach((checkTo) => {
if (item === checkTo) {
i++;
if (i === count && result.indexOf(item) === -1) {
result.push(item);
}
}
});
});
return result;
}
arr = [1,1,1,2,5,67,3,2,3,2,3,1,2,3,4,1,4];
result = getMostDuplicated(arr, 5); // result is 1
result = getMostDuplicated(arr, 2); // result 1, 2, 3, 4
console.log(result);
here is a small simple snippet to find unique and duplicate values with out sorting and two loops.
var _unique = function (arr) {_x000D_
var h = [], t = [];_x000D_
arr.forEach(function (n) {_x000D_
if (h.indexOf(n) == -1)_x000D_
h.push(n);_x000D_
else t.push(n);_x000D_
});_x000D_
return [h, t];_x000D_
}_x000D_
var result = _unique(["test",1,4,2,34,6,21,3,4,"test","prince","th",34]);_x000D_
console.log("Has duplicate values : " + (result[1].length > 0)) //and you can check count of duplicate values_x000D_
console.log(result[0]) //unique values_x000D_
console.log(result[1]) //duplicate values
_x000D_
I feel like the simplest solution would to just use indexOf
full example of pushing only unique elements to an array.
var arr = ['a','b','c','d','a','b','c','d'];
var newA = [];
for(var i = 0; i < arr.length; i++){
if(newA.indexOf(arr[i]) === -1){
newA.push(arr[i]);
}
}
Here is mine simple and one line solution.
It searches not unique elements first, then makes found array unique with the use of Set.
So we have array of duplicates in the end.
var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];_x000D_
_x000D_
console.log([...new Set(_x000D_
array.filter((value, index, self) => self.indexOf(value) !== index))]_x000D_
);
_x000D_
ES6 offers the Set data structure which is basically an array that doesn't accept duplicates. With the Set data structure, there's a very easy way to find duplicates in an array (using only one loop).
Here's my code
function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
for (let i = 0; i< arr.length; i++) {
var size = set.size;
set.add(arr[i]);
if (set.size === size) {
duplicates.add(arr[i]);
}
}
return duplicates;
}
The Prototype library has a uniq function, which returns the array without the dupes. That's only half of the work though.
Here's one without using a temp Array to store the non-duplicate ones:
// simple duplicate removal for non-object types
Array.prototype.removeSimpleDupes = function() {
var i, cntr = 0, arr = this, len = arr.length;
var uniqueVal = function(val,n,len) { // remove duplicates
var dupe = false;
for (i = n; i < len; i++) {
if (typeof arr[i]!=="undefined" && val===arr[i]) { arr.splice(i,1); dupe = true; }
}
return (dupe) ? arr.length : len;
};
while (cntr < len) {
len = uniqueVal(arr[cntr],cntr+1,len);
cntr++;
}
return arr;
};
Very simple way:
function getDuplicateValues(someArray) {_x000D_
const duplicateValues = new Set([])_x000D_
const check = new Set([])_x000D_
someArray.forEach(v => {_x000D_
if (check.has(v)) {_x000D_
duplicateValues.add(v)_x000D_
} else {_x000D_
check.add(v)_x000D_
}_x000D_
})_x000D_
return Array.from(duplicateValues);_x000D_
}_x000D_
_x000D_
const result = getDuplicateValues(['coffee', 'soda', 'water', 'juice', 'water', 'water', 'coffee'])_x000D_
_x000D_
repeated_values.textContent = JSON.stringify(result, null, ' ')
_x000D_
<pre id="repeated_values"></pre>
_x000D_
I did not like most answers.
Why? Too complicated, too much code, inefficient code and many do not answer the question, which is to find the duplicates (and not to give an array without the duplicates).
Next function returns all duplicates:
function GetDuplicates(arr) {
var i, out=[], obj={};
for (i=0; i < arr.length; i++)
obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]);
return out;
}
Because most of the time it is of no use to return ALL duplicates, but just to tell which duplicate values exist. In that case you return an array with unique duplicates ;-)
function GetDuplicates(arr) {
var i, out=[], obj={};
for (i=0; i < arr.length; i++)
obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]);
return GetUnique(out);
}
function GetUnique(arr) {
return $.grep(arr, function(elem, index) {
return index == $.inArray(elem, arr);
});
}
Maybe somebody else thinks the same.
You can use filter method and indexOf() to get all the duplicate values
function duplicate(arr) {
return duplicateArray = arr.filter((item, index) => arr.indexOf(item) !== index)
}
arr.indexOf(item) will always return the first index at which a given element can be found
using underscore.js
function hasDuplicate(arr){
return (arr.length != _.uniq(arr).length);
}
This is a single loop approach with a hash table for counting the elements and filter the array if the count is 2
, because it returns the first found duplicate.
Advantage:
var array = [5, 0, 2, 1, 2, 3, 3, 4, 4, 8, 6, 7, 9, 4],_x000D_
duplicates = array.filter((h => v => (h[v] = (h[v] || 0) + 1) === 2)({}));_x000D_
_x000D_
console.log(duplicates);
_x000D_
I am trying to improve the answer from @swilliams, this will return an array without duplicates.
// arrays for testing
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
// ascending order
var sorted_arr = arr.sort(function(a,b){return a-b;});
var arr_length = arr.length;
var results = [];
if(arr_length){
if(arr_length == 1){
results = arr;
}else{
for (var i = 0; i < arr.length - 1; i++) {
if (sorted_arr[i + 1] != sorted_arr[i]) {
results.push(sorted_arr[i]);
}
// for last element
if (i == arr.length - 2){
results.push(sorted_arr[i+1]);
}
}
}
}
alert(results);
var input = ['a', 'b', 'a', 'c', 'c'],
duplicates = [],
i, j;
for (i = 0, j = input.length; i < j; i++) {
if (duplicates.indexOf(input[i]) === -1 && input.indexOf(input[i], i+1) !== -1) {
duplicates.push(input[i]);
}
}
console.log(duplicates);
The quickest way to solve is is actually with a flag
var values = [4,2,3,1,4]_x000D_
_x000D_
// solution_x000D_
const checkDuplicate = list => {_x000D_
var hasDuplicate = false;_x000D_
list.sort().sort((a, b) => {_x000D_
if (a === b) hasDuplicate = true_x000D_
})_x000D_
return hasDuplicate_x000D_
}_x000D_
_x000D_
console.log(checkDuplicate(values))
_x000D_
This is probably one of the fastest way to remove permanently the duplicates from an array 10x times faster than the most functions here.& 78x faster in safari
function toUnique(a,b,c){//array,placeholder,placeholder
b=a.length;
while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(array);
console.log(array);
if you can't read the code above ask, read a javascript book or here are some explainations about shorter code. https://stackoverflow.com/a/21353032/2450730
EDIT
As stated in the comments this function does return an array with uniques, the question however asks to find the duplicates. in that case a simple modification to this function allows to push the duplicates into an array, then using the previous function toUnique
removes the duplicates of the duplicates.
function theDuplicates(a,b,c,d){//array,placeholder,placeholder
b=a.length,d=[];
while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(theDuplicates(array));
Here is the one of methods to avoid duplicates into javascript array...and it supports for strings and numbers...
var unique = function(origArr) {
var newArray = [],
origLen = origArr.length,
found,
x = 0; y = 0;
for ( x = 0; x < origLen; x++ ) {
found = undefined;
for ( y = 0; y < newArray.length; y++ ) {
if ( origArr[x] === newArray[y] ) found = true;
}
if ( !found) newArray.push( origArr[x] );
}
return newArray;
}
check this fiddle..
In this post was useful for duplication check if u are using Jquery.
How to find the duplicates in an array using jquery
var unique_values = {}; var list_of_values = []; $('input[name$="recordset"]'). each(function(item) { if ( ! unique_values[item.value] ) { unique_values[item.value] = true; list_of_values.push(item.value); } else { // We have duplicate values! } });
var array = ['a', 'b', 'c', 'a'];
function unique(array) {
var unique_arr = [];
array.forEach(function(i, e) {
if (unique_arr.indexOf(i)===-1) unique_arr.push(i);
});
return unique_arr;
}
console.log(unique(array));
You can make use of the sort
, filter
and sets
to do that.
var numbers = [1,2,3,4,5,6,7,8,1,2,3,4,5,3,3,4];_x000D_
var numbersSorted = numbers.sort();_x000D_
let result = numbers.filter((e, i) => numbers[i] == numbers[i+1]);_x000D_
result = [...new Set(result)];_x000D_
console.log(result);
_x000D_
Here's the simplest solution I could think of:
const arr = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'a', 'a', 'a']
const filtered = arr.filter((el, index) => arr.indexOf(el) !== index)
// => filtered = [ 2, 2, 0, 0, -1, 'a', 'a' ]
const duplicates = [...new Set(filtered)]
console.log(duplicates)
// => [ 2, 0, -1, 'a' ]
_x000D_
That's it.
Note:
It works with any numbers including 0
, strings and negative numbers e.g. -1
-
Related question: Get all unique values in a JavaScript array (remove duplicates)
The original array arr
is preserved (filter
returns the new array instead of modifying the original)
The filtered
array contains all duplicates; it can also contain more than 1 same value (e.g. our filtered array here is [ 2, 2, 0, 0, -1, 'a', 'a' ]
)
If you want to get only values that are duplicated (you don't want to have multiple duplicates with the same value) you can use [...new Set(filtered)]
(ES6 has an object Set which can store only unique values)
Hope this helps.
We will use Javascript ES6 Functionality to do magic!
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
const filtered = arr.filter((value, index) => {
return arr.indexOf(value) >= index;
});
console.log(filtered);
This is my answer from the duplicate thread (!):
When writing this entry 2014 - all examples were for-loops or jQuery. Javascript has the perfect tools for this: sort, map and reduce.
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
var uniq = names
.map((name) => {
return {
count: 1,
name: name
}
})
.reduce((a, b) => {
a[b.name] = (a[b.name] || 0) + b.count
return a
}, {})
var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)
console.log(duplicates) // [ 'Nancy' ]
_x000D_
@Dmytro-Laptin pointed out some code that can be removed. This is a more compact version of the same code. Using some ES6 tricks and higher order functions:
const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
const count = names =>
names.reduce((a, b) => ({ ...a,
[b]: (a[b] || 0) + 1
}), {}) // don't forget to initialize the accumulator
const duplicates = dict =>
Object.keys(dict).filter((a) => dict[a] > 1)
console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]
_x000D_
You can add this function, or tweak it and add it to Javascript's Array prototype:
Array.prototype.unique = function () {
var r = new Array();
o:for(var i = 0, n = this.length; i < n; i++)
{
for(var x = 0, y = r.length; x < y; x++)
{
if(r[x]==this[i])
{
alert('this is a DUPE!');
continue o;
}
}
r[r.length] = this[i];
}
return r;
}
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);
This answer might also be helpful, it leverages js reduce
operator/method to remove duplicates from array.
const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);_x000D_
_x000D_
console.log(result);
_x000D_
You can proceed by comparing index:
function getDuplicate(array) {
return array.filter((value, index) => array.value !== index)
}
Simple code with ES6 syntax (return sorted array of duplicates):
let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};
How to use:
duplicates([1,2,3,10,10,2,3,3,10]);
Here we output the duplicates just once per dupe.
var arr = [9, 9, 9, 9, 111, 2, 3, 4, 4, 5, 7];_x000D_
arr.sort(); _x000D_
_x000D_
var results = [];_x000D_
for (var i = 0; i < arr.length - 1; i++) {_x000D_
if (arr[i + 1] == arr[i]) {_x000D_
results.push(arr[i]);_x000D_
}_x000D_
}_x000D_
_x000D_
results = Array.from(new Set(results))_x000D_
_x000D_
console.log(results);
_x000D_
a.filter(( t={}, e=>!(1-(t[e]=++t[e]|0)) ))
O(n) performance; we assume your array is in a
and it contains elements that can be cast .toString()
in unique way (which is done implicity by JS in t[e]
) e.g numbers=[4,5,4], strings=["aa","bb","aa"], arraysNum=[[1,2,3], [43,2,3],[1,2,3]]. Explanation here, unique values here
var a1 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];_x000D_
var a2 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];_x000D_
var a3 = [5,6,4,9,2,3,5,3,4,1,5,4,9];_x000D_
_x000D_
let nd = (a) => a.filter((t={},e=>!(1-(t[e]=++t[e]|0)))) _x000D_
_x000D_
_x000D_
// Print_x000D_
let c= x => console.log(JSON.stringify(x)); _x000D_
c( nd(a1) );_x000D_
c( nd(a2) );_x000D_
c( nd(a3) );
_x000D_
Shortest vanilla JS:
[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]
Fast and elegant way using es6 object destructuring and reduce
It runs in O(n) (1 iteration over the array) and doesn't repeat values that appear more than 2 times
const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']_x000D_
const {_x000D_
dup_x000D_
} = arr.reduce(_x000D_
(acc, curr) => {_x000D_
acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1_x000D_
if (acc.items[curr] === 2) acc.dup.push(curr)_x000D_
return acc_x000D_
}, {_x000D_
items: {},_x000D_
dup: []_x000D_
},_x000D_
)_x000D_
_x000D_
console.log(dup)_x000D_
// ['hi', 'bye']
_x000D_
To solve the above in O(n) time complexity (without sorting).
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var obj={};
for(var i=0;i<arr.length;i++){
if(!obj[arr[i]]){
obj[arr[i]]=1;
} else {
obj[arr[i]]=obj[arr[i]]+1;
}
}
var result=[]
for(var key in obj){
if(obj[key]>1){
result.push(Number(key)) // change this to result.push(key) to find duplicate strings in an array
}
}
console.log(result)
Surprised no one posted this solution
.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>
</title>
</head>
<body>
<script>
var list = [100,33,45,54,9,12,80,100];
var newObj = {};
var newArr = [];
for(var i=0; i<list.length; i++){
newObj[list[i]] = i;
}
for(var j in newObj){
newArr.push(j);
}
console.log(newArr);
</script>
</body>
</html>
The following function (a variation of the eliminateDuplicates function already mentioned) seems to do the trick, returning test2,1,7,5 for the input ["test", "test2", "test2", 1, 1, 1, 2, 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]
Note that the problem is stranger in JavaScript than in most other languages, because a JavaScript array can hold just about anything. Note that solutions that use sorting might need to provide an appropriate sorting function--I haven't tried that route yet.
This particular implementation works for (at least) strings and numbers.
function findDuplicates(arr) {
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++) {
if (obj[arr[i]] != null) {
if (!obj[arr[i]]) {
out.push(arr[i]);
obj[arr[i]] = 1;
}
} else {
obj[arr[i]] = 0;
}
}
return out;
}
This is one of the simple ES5 solution I could think of -
function duplicates(arr) {
var duplicatesArr = [],
uniqueObj = {};
for (var i = 0; i < arr.length; i++) {
if( uniqueObj.hasOwnProperty(arr[i]) && duplicatesArr.indexOf( arr[i] ) === -1) {
duplicatesArr.push( arr[i] );
}
else {
uniqueObj[ arr[i] ] = true;
}
}
return duplicatesArr;
}
/* Input Arr: [1,1,2,2,2,1,3,4,5,3] */
/* OutPut Arr: [1,2,3] */
one liner simple way
var arr = [9,1,2,4,3,4,9]
console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates
_x000D_
This should get you what you want, Just the duplicates.
function find_duplicates(arr) {
var len=arr.length,
out=[],
counts={};
for (var i=0;i<len;i++) {
var item = arr[i];
counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
if (counts[item] === 2) {
out.push(item);
}
}
return out;
}
find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.
//program to find the duplicate elements in arraylist
import java.util.ArrayList;
import java.util.Scanner;
public class DistinctEle
{
public static void main(String args[])
{
System.out.println("Enter elements");
ArrayList<Integer> abc=new ArrayList<Integer>();
ArrayList<Integer> ab=new ArrayList<Integer>();
Scanner a=new Scanner(System.in);
int b;
for(int i=0;i<=10;i++)
{
b=a.nextInt();
if(!abc.contains(b))
{
abc.add(b);
}
else
{
System.out.println("duplicate elements"+b);
}
}
}
}
Based on @bluemoon but shorter, returns all duplicates exactly once!
function checkDuplicateKeys(arr) {
const counts = {}
return arr.filter((item) => {
counts[item] = counts[item] || 1
if (counts[item]++ === 2) return true
})
}
// [1,2,2,2,2,2,2] => [1,2]
// ['dog', 'dog', 'cat'] => ['dog']
I think the below is the easiest and fastest O(n) way to accomplish exactly what you asked:
function getDuplicates( arr ) {
var i, value;
var all = {};
var duplicates = [];
for( i=0; i<arr.length; i++ ) {
value = arr[i];
if( all[value] ) {
duplicates.push( value );
all[value] = false;
} else if( typeof all[value] == "undefined" ) {
all[value] = true;
}
}
return duplicates;
}
Or for ES5 or greater:
function getDuplicates( arr ) {
var all = {};
return arr.reduce(function( duplicates, value ) {
if( all[value] ) {
duplicates.push(value);
all[value] = false;
} else if( typeof all[value] == "undefined" ) {
all[value] = true;
}
return duplicates;
}, []);
}
Similar to a few other answers, but I used forEach()
to make it a bit prettier:
function find_duplicates(data) {
var track = {};
var duplicates = [];
data.forEach(function (item) {
!track[item] ? track[item] = true : duplicates.push(item);
});
return duplicates;
}
If a value is duplicated more than once, all its duplicates are returned, like so:
find_duplicates(['foo', 'foo', 'bar', 'bar', 'bar']);
// returns ['foo', 'bar', 'bar']
This might be what you want, otherwise you just have to follow with an "unique" filtering.
var isUnique = true;
for (var i= 0; i< targetItems.length; i++) {
var itemValue = $(targetItems[i]).val();
if (targetListValues.indexOf(itemValue) >= 0) {
isUnique = false;
break;
}
targetListValues.push(itemValue);
if (!isUnique) {
//raise any error msg
return false;
}
}
From Raphael Montanaro answer, it can improve to use with array/object item as follows.
function eliminateDuplicates(arr) {
var len = arr.length,
out = [],
obj = {};
for (var key, i=0; i < len; i++) {
key = JSON.stringify(arr[i]);
obj[key] = (obj[key]) ? obj[key] + 1 : 1;
}
for (var key in obj) {
out.push(JSON.parse(key));
}
return [out, obj];
}
Note: You need to use JSON library for browser that's not supported JSON.
function remove_dups(arrayName){
var newArray = new Array();
label:for(var i=0; i<arrayName.length; i++ ){
for(var j=0; j<newArray.length;j++ ){
if(newArray[j]==arrayName[i]){
continue label;
}
}
newArray[newArray.length] = arrayName[i];
}
return newArray;
}
Yet another way by using underscore. Numbers is the source array and dupes has possible duplicate values.
var itemcounts = _.countBy(numbers, function (n) { return n; });
var dupes = _.reduce(itemcounts, function (memo, item, idx) {
if (item > 1)
memo.push(idx);
return memo;
}, []);
Following logic will be easier and faster
// @Param:data:Array that is the source
// @Return : Array that have the duplicate entries
findDuplicates(data: Array<any>): Array<any> {
return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
}
Advantages :
Description of Logic :
Note: map() and filter() methods are efficient and faster.
//find duplicates:_x000D_
//sort, then reduce - concat values equal previous element, skip others_x000D_
_x000D_
//input_x000D_
var a = [1, 2, 3, 1, 2, 1, 2]_x000D_
_x000D_
//short version:_x000D_
var duplicates = a.sort().reduce((d, v, i, a) => i && v === a[i - 1] ? d.concat(v) : d, [])_x000D_
console.log(duplicates); //[1, 1, 2, 2]_x000D_
_x000D_
//readable version:_x000D_
var duplicates = a.sort().reduce((output, element, index, input) => {_x000D_
if ((index > 0) && (element === input[index - 1]))_x000D_
return output.concat(element)_x000D_
return output_x000D_
}, [])_x000D_
console.log(duplicates); //[1, 1, 2, 2]
_x000D_
This should be one of the shortest ways to actually find duplicate values in an array. As specifically asked for by the OP, this does not remove duplicates but finds them.
var input = [1, 2, 3, 1, 3, 1];_x000D_
_x000D_
var duplicates = input.reduce(function(acc, el, i, arr) {_x000D_
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;_x000D_
}, []);_x000D_
_x000D_
document.write(duplicates); // = 1,3 (actual array == [1, 3])
_x000D_
This doesn't need sorting or any third party framework. It also doesn't need manual loops. It works with every value indexOf() (or to be clearer: the strict comparision operator) supports.
function GetDuplicates(arr) {
var i = 0, m = [];
return arr.filter(function (n) {
return !m[n] * ~arr.indexOf(n, m[n] = ++i);
});
}
Using "includes" to test if the element already exists.
var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];_x000D_
_x000D_
for(var i = 0; i < arr.length; i++){_x000D_
if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))_x000D_
duplicates.push(arr[i])_x000D_
else_x000D_
darr.push(arr[i]);_x000D_
}_x000D_
_x000D_
console.log(duplicates);
_x000D_
<h3>Array with duplicates</h3>_x000D_
<p>[1, 1, 4, 5, 5]</p>_x000D_
<h3>Array with distinct elements</h3>_x000D_
<p>[1, 4, 5]</p>_x000D_
<h3>duplicate values are</h3>_x000D_
<p>[1, 5]</p>
_x000D_
There is a really simple way to solve this. If you use the newish 'Set' javascript command. Set can take an array as input and output a new 'Set' that only contains unique values. Then by comparing the length of the array and the 'size' property of the set you can see if they differ. If they differ it must be due to a duplicate entry.
var array1 = ['value1','value2','value3','value1']; // contains duplicates_x000D_
var array2 = ['value1','value2','value3','value4']; // unique values_x000D_
_x000D_
console.log('array1 contains duplicates = ' + containsDuplicates(array1));_x000D_
console.log('array2 contains duplicates = ' + containsDuplicates(array2));_x000D_
_x000D_
_x000D_
function containsDuplicates(passedArray) {_x000D_
let mySet = new Set(passedArray);_x000D_
if (mySet.size !== passedArray.length) {_x000D_
return true;_x000D_
}_x000D_
return false;_x000D_
}
_x000D_
If you run the above snippet you will get this output.
array1 contains duplicates = true
array2 contains duplicates = false
UPDATED: Short one-liner to get the duplicates:
[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]
To get the array without duplicates simply invert the condition:
[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]
I simply did not think about filter()
in my old answer below ;)
When all you need is to check that there are no duplicates as asked in this question you can use the every()
method:
[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true
[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false
Note that every()
doesn't work for IE 8 and below.
This should be one of the shortest and easiest ways to actually find duplicate values in an array.
var arr = [1,2,3,4,5,6,7,8,1,2,3,4,5,3,3,4];_x000D_
var data = arr.filter(function(item,index,arr){_x000D_
return arr.indexOf(item) != arr.lastIndexOf(item) && arr.indexOf(item) == index;_x000D_
})_x000D_
_x000D_
console.log(data );
_x000D_
The accepted answer is the most perfect one but as some users has pointed that for cases where an element is repeated more than 2 times it will gives us the array with repeated elements:
This solution covers that scenarios too::
const peoples = [
{id: 1, name:"Arjun"},
{id: 2, name:"quinze"},
{id: 3, name:"catorze"},
{id: 1, name:"Arjun"},
{id: 4, name:"dezesseis"},
{id: 1, name:"Arjun"},
{id: 2, name:"quinze"},
{id: 3, name:"catorzee"}
]
function repeated(ppl){
const newppl = ppl.slice().sort((a,b) => a.id -b.id);
let rept = [];
for(let i = 0; i < newppl.length-1 ; i++){
if (newppl[i+1].id == newppl[i].id){
rept.push(newppl[i+1]);
}
}
return [...new Set(rept.map(el => el.id))].map(rid =>
rept.find(el => el.id === rid)
);
}
repeated(peoples);
Here is one implemented using sort() and JSON.stringify()
https://gist.github.com/korczis/7598657
function removeDuplicates(vals) {
var res = [];
var tmp = vals.sort();
for (var i = 0; i < tmp.length; i++) {
res.push(tmp[i]);
while (JSON.stringify(tmp[i]) == JSON.stringify(tmp[i + 1])) {
i++;
}
}
return res;
}
console.log(removeDuplicates([1,2,3,4,5,4,3,3,2,1,]));
Modifying @RaphaelMontanaro's solution, borrowing from @Nosredna's blog, here is what you could do if you just want to identify the duplicate elements from your array.
function identifyDuplicatesFromArray(arr) {
var i;
var len = arr.length;
var obj = {};
var duplicates = [];
for (i = 0; i < len; i++) {
if (!obj[arr[i]]) {
obj[arr[i]] = {};
}
else
{
duplicates.push(arr[i]);
}
}
return duplicates;
}
Thanks for the elegant solution, @Nosredna!
I have just figured out a simple way to achieve this using an Array filter
var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];_x000D_
_x000D_
// Filter 1: to find all duplicates elements_x000D_
var duplicates = list.filter(function(value,index,self) {_x000D_
return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;_x000D_
});_x000D_
_x000D_
console.log(duplicates);
_x000D_
//
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
arr2 = [1,2,511,12,50],
arr3 = [22,0],
merged,
nonUnique;
// Combine all the arrays to a single one
merged = arr.concat(arr2, arr3)
// create a new (dirty) Array with only the non-unique items
nonUnique = merged.filter((item,i) => merged.includes(item, i+1))
// Cleanup - remove duplicate & empty items items
nonUnique = [...new Set(nonUnique)]
console.log(nonUnique)
_x000D_
In the below example I chose to superimpose a unique
method on top of the Array
prototype, allowing access from everywhere and has more "declarative" syntax. I do not recommend this approach on large projects, since it might very well collide with another method with the same custom name.
Array.prototype.unique = function () {
var arr = this.sort(), i=arr.length; // input must be sorted for this to work
while(i--)
arr[i] === arr[i-1] && arr.splice(i,1) // remove duplicate item
return arr
}
Array.prototype.nonunique = function () {
var arr = this.sort(), i=arr.length, res = []; // input must be sorted for this to work
while(i--)
arr[i] === arr[i-1] && (res.indexOf(arr[i]) == -1) && res.push(arr[i])
return res
}
//
var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
arr2 = [1,2,511,12,50],
arr3 = [22,0],
// merge all arrays & call custom Array Prototype - "unique"
unique = arr.concat(arr2, arr3).unique(),
nonunique = arr.concat(arr2, arr3).nonunique()
console.log(unique) // [1,12,2,22,3,4,5,50,511,6,7,8]
console.log(nonunique) // [1,12,2,22,3,4,5,50,511,6,7,8]
_x000D_
Higher ranked answers have a few inherent issues including the use of legacy javascript, incorrect ordering or with only support for 2 duplicated items.
Here's a modern solution which fixes those problems:
const arrayNonUniq = array => {
if (!Array.isArray(array)) {
throw new TypeError("An array must be provided!")
}
return array.filter((value, index) => array.indexOf(value) === index && array.lastIndexOf(value) !== index)
}
arrayNonUniq([1, 1, 2, 3, 3])
//=> [1, 3]
arrayNonUniq(["foo", "foo", "bar", "foo"])
//=> ['foo']
You can also use the npm package array-non-uniq
.
I prefer the function way of doing this.
function removeDuplicates(links) {
return _.reduce(links, function(list, elem) {
if (list.indexOf(elem) == -1) {
list.push(elem);
}
return list;
}, []);
}
This uses underscore, but Array has a reduce
function, too
This is most efficient way i can think of as doesn't include Array.indexOf()
or Array.lastIndexOf()
which have complexity of O(n) and using inside any loop of complexity O(n) will make complete complexity O(n^2).
My first loop have complexity of O(n/2) or O((n/2) + 1), as complexity of search in hash is O(1). The second loop worst complexity when there's no duplicate in array is O(n) and best complexity when every element have a duplicate is O(n/2).
function duplicates(arr) {
let duplicates = [],
d = {},
i = 0,
j = arr.length - 1;
// Complexity O(n/2)
while (i <= j) {
if (i === j)
d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1; // Complexity O(1)
else {
d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1; // Complexity O(1)
d[arr[j]] ? d[arr[j]] += 1 : d[arr[j]] = 1; // Complexity O(1)
}
++i;
--j;
}
// Worst complexity O(n), best complexity O(n/2)
for (let k in d) {
if (d[k] > 1)
duplicates.push(k);
}
return duplicates;
}
console.log(duplicates([5,6,4,9,2,3,5,3,4,1,5,4,9]));
console.log(duplicates([2,3,4,5,4,3,4]));
console.log(duplicates([4,5,2,9]));
console.log(duplicates([4,5,2,9,2,5,9,4]));
var arr = [2, 1, 2, 2, 4, 4, 2, 5];_x000D_
_x000D_
function returnDuplicates(arr) {_x000D_
return arr.reduce(function(dupes, val, i) {_x000D_
if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {_x000D_
dupes.push(val);_x000D_
}_x000D_
return dupes;_x000D_
}, []);_x000D_
}_x000D_
_x000D_
alert(returnDuplicates(arr));
_x000D_
This function avoids the sorting step and uses the reduce() method to push duplicates to a new array if it doesn't already exist in it.
With ES6 (or using Babel or Typescipt) you can simply do:
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);
Here is a very light and easy way:
var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
if (codes.indexOf(codes[i]) != i) {
codes.splice(i,1);
}
}
This is how I implemented it with map. It should run in O(n) time and should kinda be easy to gasp.
var first_array=[1,1,2,3,4,4,5,6];_x000D_
var find_dup=new Map;_x000D_
_x000D_
for (const iterator of first_array) {_x000D_
// if present value++_x000D_
if(find_dup.has(iterator)){ _x000D_
find_dup.set(iterator,find_dup.get(iterator)+1); _x000D_
}else{_x000D_
// else add it_x000D_
find_dup.set(iterator,1);_x000D_
}_x000D_
}_x000D_
console.log(find_dup.get(2));
_x000D_
Then you can find_dup.get(key)
to find if it has duplicates (it should give > 1).
If you want to elimate the duplicates, try this great solution:
function eliminateDuplicates(arr) {
var i,
len = arr.length,
out = [],
obj = {};
for (i = 0; i < len; i++) {
obj[arr[i]] = 0;
}
for (i in obj) {
out.push(i);
}
return out;
}
Source: http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/
Returns duplicates and preserves data type.
const dupes = arr => {
const map = arr.reduce((map, curr) => {
return (map.set(curr, (map.get(curr) || 0) + 1), map)
}, new Map());
return Array.from(map).filter(([key, val])=> val > 1).map(([key, val]) => key)
}
const dupes = arr => {
const map = arr.reduce((map, curr) => {
return (map.set(curr, (map.get(curr) || 0) + 1), map)
}, new Map());
const dupes_ = [];
for (let [key, val] of map.entries()) {
if (val > 1) dupes_.push(key);
}
return dupes_;
}
This will return duplicates from an Array as an Array of duplicates.
const duplicates = function(arr) {_x000D_
// let try moving in pairs.. maybe that will work_x000D_
let dups = new Set(),_x000D_
r = []_x000D_
arr.sort()_x000D_
arr.reduce((pv, cv) => {_x000D_
if (pv === cv) {_x000D_
dups.add(pv)_x000D_
}_x000D_
return cv_x000D_
})_x000D_
for (let m of dups.values()) {_x000D_
r.push(m)_x000D_
}_x000D_
return r_x000D_
}_x000D_
_x000D_
console.log(duplicates([1,3,5,6,7,4,4,5,1,4,6,3,8,9,5,0]))
_x000D_
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});
or when added to the prototyp.chain of Array
//copy and paste: without error handling
Array.prototype.unique =
function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}
See here: https://gist.github.com/1305056
var arr = [1,2,3,4,13,2,3,4,3,4];_x000D_
_x000D_
// non_unique Printing _x000D_
function nonUnique(arr){_x000D_
var result = [];_x000D_
for(var i =0;i<arr.length;i++){_x000D_
if(arr.indexOf(arr[i],i+1) > -1){_x000D_
result.push(arr[i]);_x000D_
}_x000D_
}_x000D_
console.log(result);_x000D_
}nonUnique(arr);_x000D_
_x000D_
// unique Printing_x000D_
function uniqueDuplicateVal(arr){_x000D_
var result = [];_x000D_
for(var i =0;i<arr.length;i++){_x000D_
if(arr.indexOf(arr[i],i+1) > -1){_x000D_
if(result.indexOf(arr[i]) === -1]){_x000D_
result.push(arr[i]);_x000D_
}_x000D_
}_x000D_
} _x000D_
}_x000D_
uniqueDuplicateVal(arr)
_x000D_
using Pure Js
function arr(){
var a= [1,2,3,4,5,34,2,5,7,8,6,4,3,25,8,34,56,7,8,76,4,23,34,46,575,8564,53,5345657566];
var b= [];
b.push(a[0]);
var z=0;
for(var i=0; i< a.length; i++){
for(var j=0; j< b.length; j++){
if(b[j] == a[i]){
z = 0;
break;
}
else
z = 1;
}
if(z)
b.push(a[i]);
}
console.log(b);
}
var a = ["a","a","b","c","c"];
a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
Source: Stackoverflow.com