Say I have an array like this: [1, 1, 2, 2, 3]
I want to get the duplicates which are in this case: [1, 2]
Does lodash support this? I want to do it in the shortest way possible.
Say I have an array like this: [1, 1, 2, 2, 3]
I want to get the duplicates which are in this case: [1, 2]
Does lodash support this? I want to do it in the shortest way possible.
You can use this:
_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1))
or without using lodash, you can use plain JavaScript:
arr.filter((val, i) => arr.includes(val, i + 1))
Note: that if a number appears more than two times in your array you can always use _.uniq.
const duplicates = _.filter(array, (value, index, iteratee) => _.includes(iteratee, value, index + 1))_.find instead of _.includes _.filter(array, (value, index, iteratee) => { return _.find(iteratee, value, index + 1) })iteratee===array this is equivalent to a nested loop for(;;){ for(;;){iteratee===array mean?var array = [1, 1, 2, 2, 3];
var groupped = _.groupBy(array, function (n) {return n});
var result = _.uniq(_.flatten(_.filter(groupped, function (n) {return n.length > 1})));
This works for unsorted arrays as well.
Another way, but using filters and ecmaScript 2015 (ES6)
var array = [1, 1, 2, 2, 3];
_.filter(array, v =>
_.filter(array, v1 => v1 === v).length > 1);
//→ [1, 1, 2, 2]
How about using countBy() followed by reduce()?
const items = [1,1,2,3,3,3,4,5,6,7,7];
const dup = _(items)
.countBy()
.reduce((acc, val, key) => val > 1 ? acc.concat(key) : acc, [])
.map(_.toNumber)
console.log(dup);
// [1, 3, 7]
Pure JS solution:
export function hasDuplicates(array) {
return new Set(array).size !== array.length
}
For an array of objects:
/**
* Detects whether an array has duplicated objects.
*
* @param array
* @param key
*/
export const hasDuplicatedObjects = <T>(array: T[], key: keyof T): boolean => {
const _array = array.map((element: T) => element[key]);
return new Set(_array).size !== _array.length;
};
Here is another concise solution:
let data = [1, 1, 2, 2, 3]
let result = _.uniq(_.filter(data, (v, i, a) => a.indexOf(v) !== i))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
_.uniq takes care of the dubs which _.filter comes back with.
Same with ES6 and Set:
let data = [1, 1, 2, 2, 3]
let result = new Set(data.filter((v, i, a) => a.indexOf(v) !== i))
console.log(Array.from(result))
here is mine, es6-like, deps-free, answer. with filter instead of reducer
// this checks if elements of one list contains elements of second list
// example code
[0,1,2,3,8,9].filter(item => [3,4,5,6,7].indexOf(item) > -1)
// function
const contains = (listA, listB) => listA.filter(item => listB.indexOf(item) > -1)
contains([0,1,2,3], [1,2,3,4]) // => [1, 2, 3]
// only for bool
const hasDuplicates = (listA, listB) => !!contains(listA, listB).length
edit: hmm my bad is: I've read q as general question but this is strictly for lodash, however my point is - you don't need lodash in here :)
You can make use of a counter object. This will have each number as key and total number of occurrence as their value. You can use filter to get the numbers when the counter for the number becomes 2
const array = [1, 1, 2, 2, 3],
counter = {};
const duplicates = array.filter(n => (counter[n] = counter[n] + 1 || 1) === 2)
console.log(duplicates)