Javascript: Most Efficient Way of Summing Multiple Arrays by Key - javascript

I have a JSON object returned from a web service, which is an array of objects. I need to add the "data" arrays together to form a summed array. The JSON response looks like this:
[
{
"data":[
0,3,8,2,5
],
"someKey":"someValue"
},
{
"data":[
3,13,1,0,5
],
"someKey":"someOtherValue"
}
]
There could be N amount of objects in the array. The desired output for the above example would be:
[3, 16, 9, 2, 10]
I was intending on creating an empty array variable (var arr), then looping over the objects, and for each object, loop through the "data" key and for each key increment the corresponding key in arr by the value.
Is there a more efficient way of doing this using some sort of merge function?

How about this, I believe it should work for all cases.
var data = [{
"data": [
0, 3, 8, 2, 5
],
"someKey": "someValue"
}, {
"data": [
3, 13, 1, 0, 5
],
"someKey": "someOtherValue"
}];
var datas = data.reduce(function(a, b) {
b.data.forEach(function(x, i) {
a[i] = a[i] || 0;
a[i] += x;
});
return a;
}, []);
console.log(datas);

If every object has the same data length, you can try with:
var input; // Your input data
var output = [];
for (var i = 0; i < input[0].data.length; i++) {
output[i] = input.reduce(function(prev, item) {
return +(item.data[i]) + prev;
}, 0);
}
console.log(output);
// [3, 16, 9, 2, 10]
If every object has different data size:
var input; // Your input data
var i = 0, output = [];
while (true) {
var outOfIndex = true;
var sum = input.reduce(function(prev, item) {
if (item.data[i] !== undefined) {
outOfIndex = false;
}
return +(item.data[i]) + prev;
}, 0);
if (outOfIndex) {
break;
}
output[i++] = sum;
}
console.log(output);
// [3, 16, 9, 2, 10]

Slightly less imperative solution:
//zip takes two arrays and combines them per the fn argument
function zip(left, right, fn) {
var shorter = (right.length > left.length) ? left : right;
return shorter.map(function(value, i) {
return fn(left[i], right[i]);
});
}
//assuming arr is your array of objects. Because were using
//zip, map, and reduce, it doesn't matter if the length of the
//data array changes
var sums = arr
.map(function(obj) { return obj.data; })
.reduce(function(accum, array) {
//here we want to combine the running totals w/the current data
return zip(accum, array, function(l, r) { return l + r; });
});

Related

Remove similar duplicates from 2D array in JavaScript

I need to remove similar duplicates as well as real duplicates from 2D array in JavaScript.
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
for(var i = 0, l = arr.length; i < l; i++) {
var stringified = JSON.stringify(arr[i]);
if(itemsFound[stringified]) continue;
uniques.push(arr[i]);
itemsFound[stringified] = true;
}
return uniques;
}
a=makeUnique(a)
console.log(a);
I have got this output:
[ [ 5, 6 ], [ 1, 1 ], [ 6, 5 ], [ 3, 2 ], [ 2, 3 ] ]
Correct should be:
[ [ 5, 6 ], [ 1, 1 ], [ 2, 3 ] ]
My code removes correctly duplicates, but I need to remove similar duplicates also.
For example if I have [3,2] and [2,3] I should remove [3,2] (the one which has bigger starting index value.)
Could you help me to fix this?
Here is an example of how you can do it:
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
arr.sort((a, b) => a[0] + a[1] - (b[0] + b[1]))
for (var i = 0, l = arr.length; i < l; i++) {
if (!itemsFound[arr[i]] && !itemsFound[[arr[i][1], arr[i][1]]]) {
uniques.push(arr[i]);
itemsFound[arr[i]] = true;
itemsFound[[arr[i][1], arr[i][0]]] = true;
}
}
return uniques;
}
I hope it helps.
There are two parts
similar should be considered
among similar, one with smaller first key should stay
1. Similar should be considered
Here you can just make the key for hashmap in such a way that similar items produce same key.
One way to do that is sort the items in the tuple and then form the key, as there are two items only, first one will be min and second one will be max
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUnique(arr) {
var uniques = [];
var itemsFound = {};
for(var i = 0, l = arr.length; i < l; i++) {
let [a,b] = arr[i];
const hashKey = [ Math.min(a,b), Math.max(a,b)];
var stringified = JSON.stringify(hashKey);
if(itemsFound[stringified]) continue;
uniques.push(arr[i]);
itemsFound[stringified] = true;
}
return uniques;
}
let ans1=makeUnique(a)
console.log(ans1);
2. Among similar, the one with smaller first key should stay
Now you can remember in the hashmap what the value for a key was and keep updating it based on the correct candidate
let a = [
[5, 6],
[1,1],
[6,5],
[1,1],
[3,2],
[2,3]
]
function makeUniqueSmallerFirst(arr) {
var items = {};
for(var i = 0, l = arr.length; i < l; i++) {
let [a,b] = arr[i];
const hashKey = [ Math.min(a,b), Math.max(a,b)];
var stringified = JSON.stringify(hashKey);
if (stringified in items) {
let previous = items[stringified];
if (previous[0] > arr[i][0]) {
items[stringified] = arr[i];
}
} else {
items[stringified] = arr[i] // I am just storing the array because if I see a similar item next time, I can compare if that has first item smaller or not
}
}
return Object.values(items); // this doesn't guarantee output order though
// if you want order as well . you can iterate over input array once more and arrange the items in the preferred order.
}
let ans2=makeUniqueSmallerFirst(a)
console.log(ans2);
UPDATED (More simple and faster example for ES5+):
function makeUnique(arr) {
return new Set(a.map(
arr => JSON.stringify(arr.sort((a, b) => a - b)))
)
}
const m = makeUnique(a)
console.log(m) //
OLD:
This is an example of code that makes a two-dimensional array with arrays of any length unique.
let a = [
[5, 6],
[1, 1],
[6, 5],
[1, 5],
[3, 2],
[2, 3],
[6, 5, 3],
[3, 5, 6]
]
function isUnique(uniqueArray, checkedArray) {
let checked = [...checkedArray];
let unique = [...uniqueArray];
let uniqueValue = 0;
unique.forEach(value => {
if (checked.includes(value)) {
checked.splice(checked.indexOf(value), 1)
} else uniqueValue++;
})
return uniqueValue > 0;
}
function makeUnique(array2d) {
let unique = [array2d[0]]
array2d.forEach(checkedArray => {
if (unique.some(uniqueArray => {
if (checkedArray.length !== uniqueArray.length) return false;
return !isUnique(uniqueArray, checkedArray)
}
)) return 0;
else unique.push(checkedArray)
})
return unique
}
console.log(makeUnique(a)) // [ [ 5, 6 ], [ 1, 1 ], [ 1, 5 ], [ 3, 2 ], [ 6, 5, 3 ] ]
isUnique() this function checks if the numbers in both arrays are unique, and if they are, it outputs true. We use the copy through spread operator, so that when you delete a number from an array, the array from outside is not affected.
makeUnique() function makes the array unique, in the following way:
It checks if our unique two-dimensional array has at least one array that is identical to checkedArray
The first check if the arrays are of different lengths - they are unique, skip and check for uniqueness, if !isUnique gives out true, then the array is skipped by return 0

Find all duplicates in array of objects [duplicate]

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.
Similar question:
Get all unique values in a JavaScript array (remove duplicates)
You could sort the array and then run through it and then see if the next (or previous) index is the same as the current. Assuming your sort algorithm is good, this should be less than O(n2):
const findDuplicates = (arr) => {
let sorted_arr = arr.slice().sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
// (we use slice to clone the array so the
// original array won't be modified)
let results = [];
for (let i = 0; i < sorted_arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
return results;
}
let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);
In case, if you are to return as a function for duplicates. This is for similar type of case.
Reference: https://stackoverflow.com/a/57532964/8119511
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;
}
console.log(eliminateDuplicates([1,6,7,3,6,8,1,3,4,5,1,7,2,6]))
Source:
http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/
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.
Find duplicate items
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
const uniq = names
.map((name) => {
return {
count: 1,
name: name
};
})
.reduce((result, b) => {
result[b.name] = (result[b.name] || 0) + b.count;
return result;
}, {});
const duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1);
console.log(duplicates); // [ 'Nancy' ]
More functional syntax:
#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((result, value) => ({ ...result,
[value]: (result[value] || 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' ]
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]
Note that this answer’s main goal is to be short. If you need something performant for a big array, one possible solution is to sort your array first (if it is sortable) then do the following to get the same kind of results as above:
myHugeSortedArray.filter((e, i, a) => a[i-1] === e)
Here is an example for a 1 000 000 integers array:
const myHugeIntArrayWithDuplicates =
[...Array(1_000_000).keys()]
// adding two 0 and four 9 duplicates
.fill(0, 2, 4).fill(9, 10, 14)
console.time("time")
console.log(
myHugeIntArrayWithDuplicates
// a possible sorting method for integers
.sort((a, b) => a > b ? 1 : -1)
.filter((e, i, a) => a[i-1] === e)
)
console.timeEnd("time")
On my AMD Ryzen 7 5700G dev machine it outputs:
[ 0, 0, 9, 9, 9, 9 ]
time: 22.738ms
As pointed out in the comments both the short solution and the performant solution will return an array with several time the same duplicate if it occurs more than once in the original array:
[1, 1, 1, 2, 2, 2, 2].filter((e, i, a) => a.indexOf(e) !== i) // [1, 1, 2, 2, 2]
If unique duplicates are wanted then a function like
function duplicates(arr) {
return [...new Set(arr.filter((e, i, a) => a.indexOf(e) !== i))]
}
can be used so that duplicates([1, 1, 1, 2, 2, 2, 2]) returns [1, 2].
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.
Find duplicate values in an array
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];
var duplicates = input.reduce(function(acc, el, i, arr) {
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);
document.write(duplicates); // = 1,3 (actual array == [1, 3])
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.
Because of reduce() and indexOf() it needs at least IE 9.
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);
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;
}
});
}
var a = ["a","a","b","c","c"];
a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
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.
Find non-unique values from 3 arrays (or more):
ES2015
// 🚩🚩 🚩 🚩 🚩
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)
PRE-ES2015:
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]
using underscore.js
function hasDuplicate(arr){
return (arr.length != _.uniq(arr).length);
}
The simplest and quickest way is to use the Set object:
const numbers = [1, 2, 3, 2, 4, 5, 5, 6];
const set = new Set(numbers);
const duplicates = numbers.filter(item => {
if (set.has(item)) {
set.delete(item);
return false;
} else {
return true;
}
});
// OR more concisely
const duplicates = numbers.filter(item => !set.delete(item));
console.log(duplicates);
// [ 2, 5 ]
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]
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' ]
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.
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];
console.log([...new Set(
array.filter((value, index, self) => self.indexOf(value) !== index))]
);
Shortest vanilla JS:
[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]
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
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
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']
const {
dup
} = arr.reduce(
(acc, curr) => {
acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
if (acc.items[curr] === 2) acc.dup.push(curr)
return acc
}, {
items: {},
dup: []
},
)
console.log(dup)
// ['hi', 'bye']
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
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] );
});
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);
}
}
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;
}
With ES6 (or using Babel or Typescipt) you can simply do:
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);
https://es6console.com/j58euhbt/
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]);
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];
// Filter 1: to find all duplicates elements
var duplicates = list.filter(function(value,index,self) {
return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
});
console.log(duplicates);
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], []);
console.log(result);
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.
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;
}
var arr = [2, 1, 2, 2, 4, 4, 2, 5];
function returnDuplicates(arr) {
return arr.reduce(function(dupes, val, i) {
if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
dupes.push(val);
}
return dupes;
}, []);
}
alert(returnDuplicates(arr));
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.

How to create an unique combination of array elements in Javascript?

I have an array of object where I want to create every unique combination of objects as its own array. The combinations also need to include a different number of elements and should work regardless of the elements provided. To simplify the problem let's say we have the following array.
let arr = [1, 2, 3];
The result in this situation would be the following:
[1]
[2]
[3]
[1, 2]
[1, 3]
[2, 3]
[1, 2, 3]
I have looked for a solution and have found an approach using cartesian products, but this doesn't really seem to apply for this case since i need unique combinations and no replicates. How can I a approach this problem with Javascript?
You could take a recursive approach and return an array of items.
function combinations(array) {
function iter(index, temp = []) {
if (!index--) return;
iter(index, temp);
result.push(temp = [array[index], ...temp]);
iter(index, temp);
}
var result = [];
iter(array.length);
return result;
}
combinations([1, 2, 3]).forEach(a => console.log(a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
This can be defined recursively in pseudo-Javascript:
function combos(arr) {
if arr is empty
return arr;
else {
result = [];
// for every combination from the rest of the list
for x in combos( arr.slice(1) ) {
// get that combination w/o arr[0]
result.push( x );
x.push( arr[0] );
// … and the combination w/ arr[0]
result.push( x );
}
}
}
I managed to create a solution on my own. I created two helper functions for making the problem easier. The first one is just a function for switching array indexes and the second one is a recursive function that let's me remove an element at each recursive call and sums the result to its own array.
By iterating for every element i can get all the n-length combinations for the array. Then I remove the first element and repeat the procedure until i am out of elements. This will give me all the solutions, but they will have duplicates.
By sorting them ascending and converting them to a string i can create a Set out of them, which will create unique strings. The last step is to remove the duplicates and I end up with all the combinations.
let arr = [1, 2, 3];
let result = [];
while (arr.length !== 0) {
for (let i = 0; i < arr.length; i++) {
result = [...result, ...levelCombo(arr)];
arr = switchIndex(arr, 0, i);
}
arr = arr.slice(1);
}
result = result.map(el => JSON.stringify(el.sort()));
let uniqueResult = [...new Set(result)].map(el => JSON.parse(el));
console.log(uniqueResult);
function switchIndex(arr, a, b) {
let val1 = arr[a];
let val2 = arr[b];
arr[a] = val2;
arr[b] = val1;
return arr;
}
function levelCombo(arr) {
let result = [];
if (arr.length === 0) {
return [];
}
for (let i = 0; i < arr.length; i++) {
result.push(arr[i]);
}
result = [result, ...levelCombo(arr.slice(1))];
return result;
}
For the input [1, 2, 3] the printed result will be the following:
[
[ 1, 2, 3 ],
[ 2, 3 ],
[ 3 ],
[ 1, 3 ],
[ 1, 2 ],
[ 2 ],
[ 1 ]
]

Return sorted unique values from array, but if count is equal, return values in order

I am creating a function that takes in an array of unsorted integers and returns an array of the unique integers, sorted by frequency. However, if the integers have the same frequency, they will be returned in the original order of the input array. Here is my current function:
function uniqueUnionSorted(arr) {
counter = {};
for(var i=0; i<arr.length; i++) {
if (arr[i] in counter) {
counter[arr[i]] ++;
} else {
counter[arr[i]] = 1;
}
}
sortedStrings = Object.keys(counter).sort(function(a,b) {
return counter[b] - counter[a]
});
var sortedNumbers = sortedStrings.map(Number);
return sortedNumbers;
}
So for an array like this:
arr = [1, 3, 2, 1, 5, 2, 1, 4]
the function should return:
[1,2,3,5,4]
However, my function is sorting the 5 and 4 and is returning:
[1,2,3,4,5]
Please help!
The cause of this reordering is that object properties that are numerical will come out ordered when using Object.keys().
Instead of defining counter as an object, use a Map, which will retain the insertion order:
function uniqueUnionSorted(arr) {
var counter = new Map();
for(var i=0; i<arr.length; i++) {
counter.set(arr[i], (counter.get(arr[i]) || 0) + 1);
}
// Spreading the Map will produce an array of pairs
var sortedNumbers = [...counter].sort(function(a,b) {
return b[1] - a[1]; // sort by count
}).map(a => a[0]); // only keep the values, not the counts
return sortedNumbers; // Map keys retain original type, so they remain numeric
}
arr = [1, 3, 2, 1, 5, 2, 1, 4]
console.log(uniqueUnionSorted(arr));
In counter object we can also save lowest index of each element so we can keep elements with lower index earlier in sorted array.
function uniqueUnionSorted(arr) {
counter = {};
for(var i=0; i<arr.length; i++) {
if (arr[i] in counter) {
counter[arr[i]].count ++;
} else {
counter[arr[i]] = {'count' : 1, 'index' : i}; //save lowest index of element
}
}
sortedStrings = Object.keys(counter).sort(function(a,b) {
return counter[b].count - counter[a].count || counter[a].index - counter[b].index;
});
var sortedNumbers = sortedStrings.map(Number);
return sortedNumbers;
}
console.log(uniqueUnionSorted([1, 3, 2, 1, 5, 2, 1, 4]));
https://jsfiddle.net/anLrwwfa/4/
Here's another way you could do this using a Set object, an object to store frequency, and the original array to keep the origin intact. It's a bit longer than the current popular answer but I was in the midst of writing it, so I figured I would throw my hat in the ring.
function sortArr(arr) {
let uniqueValues = new Set();
let frequencies = new Object();
//add values to set object
arr.map((val) => uniqueValues.add(val));
//get frequencies of values
for (let val of uniqueValues) {
frequencies[val] = 0;
}
arr.map((val) => frequencies[val]++);
//sort by frequency, then sort by original placement in array
let sorted_arr = Array.from(uniqueValues).sort((a, b) => {
return frequencies[a] - frequencies[b];
}).sort((a, b) => {
return (frequencies[a] === frequencies[b]) ?
Array.from(uniqueValues).indexOf(a) - Array.from(uniqueValues).indexOf(b) :
b;
});
//return array
return sorted_arr;
};
sortArr([1, 3, 2, 1, 5, 2, 1, 4]); //1,2,3,5,4
EDIT
optimized code a bit
May add an additional condition to actually sort after the original array index if the frequency is equal:
sortedStrings = Object.keys(counter).sort(function(a,b) {
return counter[b] - counter[a] || arr.indexOf(+a)-arr.indexOf(+b)
});
http://jsbin.com/zewulanozo/edit?console

How to find duplicated values in an Array [duplicate]

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.
Similar question:
Get all unique values in a JavaScript array (remove duplicates)
You could sort the array and then run through it and then see if the next (or previous) index is the same as the current. Assuming your sort algorithm is good, this should be less than O(n2):
const findDuplicates = (arr) => {
let sorted_arr = arr.slice().sort(); // You can define the comparing function here.
// JS by default uses a crappy string compare.
// (we use slice to clone the array so the
// original array won't be modified)
let results = [];
for (let i = 0; i < sorted_arr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
return results;
}
let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);
In case, if you are to return as a function for duplicates. This is for similar type of case.
Reference: https://stackoverflow.com/a/57532964/8119511
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;
}
console.log(eliminateDuplicates([1,6,7,3,6,8,1,3,4,5,1,7,2,6]))
Source:
http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/
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.
Find duplicate items
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
const uniq = names
.map((name) => {
return {
count: 1,
name: name
};
})
.reduce((result, b) => {
result[b.name] = (result[b.name] || 0) + b.count;
return result;
}, {});
const duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1);
console.log(duplicates); // [ 'Nancy' ]
More functional syntax:
#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((result, value) => ({ ...result,
[value]: (result[value] || 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' ]
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]
Note that this answer’s main goal is to be short. If you need something performant for a big array, one possible solution is to sort your array first (if it is sortable) then do the following to get the same kind of results as above:
myHugeSortedArray.filter((e, i, a) => a[i-1] === e)
Here is an example for a 1 000 000 integers array:
const myHugeIntArrayWithDuplicates =
[...Array(1_000_000).keys()]
// adding two 0 and four 9 duplicates
.fill(0, 2, 4).fill(9, 10, 14)
console.time("time")
console.log(
myHugeIntArrayWithDuplicates
// a possible sorting method for integers
.sort((a, b) => a > b ? 1 : -1)
.filter((e, i, a) => a[i-1] === e)
)
console.timeEnd("time")
On my AMD Ryzen 7 5700G dev machine it outputs:
[ 0, 0, 9, 9, 9, 9 ]
time: 22.738ms
As pointed out in the comments both the short solution and the performant solution will return an array with several time the same duplicate if it occurs more than once in the original array:
[1, 1, 1, 2, 2, 2, 2].filter((e, i, a) => a.indexOf(e) !== i) // [1, 1, 2, 2, 2]
If unique duplicates are wanted then a function like
function duplicates(arr) {
return [...new Set(arr.filter((e, i, a) => a.indexOf(e) !== i))]
}
can be used so that duplicates([1, 1, 1, 2, 2, 2, 2]) returns [1, 2].
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.
Find duplicate values in an array
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];
var duplicates = input.reduce(function(acc, el, i, arr) {
if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);
document.write(duplicates); // = 1,3 (actual array == [1, 3])
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.
Because of reduce() and indexOf() it needs at least IE 9.
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);
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;
}
});
}
var a = ["a","a","b","c","c"];
a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
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.
Find non-unique values from 3 arrays (or more):
ES2015
// 🚩🚩 🚩 🚩 🚩
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)
PRE-ES2015:
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]
using underscore.js
function hasDuplicate(arr){
return (arr.length != _.uniq(arr).length);
}
The simplest and quickest way is to use the Set object:
const numbers = [1, 2, 3, 2, 4, 5, 5, 6];
const set = new Set(numbers);
const duplicates = numbers.filter(item => {
if (set.has(item)) {
set.delete(item);
return false;
} else {
return true;
}
});
// OR more concisely
const duplicates = numbers.filter(item => !set.delete(item));
console.log(duplicates);
// [ 2, 5 ]
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]
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' ]
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.
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];
console.log([...new Set(
array.filter((value, index, self) => self.indexOf(value) !== index))]
);
Shortest vanilla JS:
[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]
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
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
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']
const {
dup
} = arr.reduce(
(acc, curr) => {
acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
if (acc.items[curr] === 2) acc.dup.push(curr)
return acc
}, {
items: {},
dup: []
},
)
console.log(dup)
// ['hi', 'bye']
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
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] );
});
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);
}
}
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;
}
With ES6 (or using Babel or Typescipt) you can simply do:
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);
https://es6console.com/j58euhbt/
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]);
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];
// Filter 1: to find all duplicates elements
var duplicates = list.filter(function(value,index,self) {
return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
});
console.log(duplicates);
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], []);
console.log(result);
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.
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;
}
var arr = [2, 1, 2, 2, 4, 4, 2, 5];
function returnDuplicates(arr) {
return arr.reduce(function(dupes, val, i) {
if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
dupes.push(val);
}
return dupes;
}, []);
}
alert(returnDuplicates(arr));
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.

Categories