Ответ 1
Вы можете использовать это:
_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1));
Обратите внимание, что если число появляется в вашем массиве более двух раз, вы всегда можете использовать _.uniq
.
Скажем, у меня есть такой массив: [1, 1, 2, 2, 3]
Я хочу получить дубликаты, которые в этом случае: [1, 2]
Поддерживает ли это lodash? Я хочу сделать это как можно короче.
Вы можете использовать это:
_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1));
Обратите внимание, что если число появляется в вашем массиве более двух раз, вы всегда можете использовать _.uniq
.
Другой способ состоит в том, чтобы группировать по уникальным элементам и возвращать групповые ключи с более чем 1 элементом
_([1, 1, 2, 2, 3]).groupBy().pickBy(x => x.length > 1).keys().value()
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})));
Это также работает с несортированными массивами.
Другой способ, но использование фильтров и ecmaScript 2015 (ES6)
var array = [1, 1, 2, 2, 3];
_.filter(array, v =>
_.filter(array, v1 => v1 === v).length > 1);
//→ [1, 1, 2, 2]
Как насчет использования countBy()
, за которым следует 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]
Ну, вы можете использовать этот фрагмент кода, который намного быстрее, так как он имеет сложность O (n), и это не использует Lodash.
[1, 1, 2, 2, 3]
.reduce((agg,col) => {
agg.filter[col] = agg.filter[col]? agg.dup.push(col): 2;
return agg
},
{filter:{},dup:[]})
.dup;
//result:[1,2]
вот мой, es6-like, deps-free, ответ. с фильтром вместо редуктора
// 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
редактировать: хм мой плохой: я прочитал q как общий вопрос, но это строго для lodash, однако моя точка зрения - вам не нужен lodash здесь :)
Надеюсь, что решение ниже поможет вам, и оно будет полезно в любых условиях
hasDataExist(listObj, key, value): boolean {
return _.find(listObj, function(o) { return _.get(o, key) == value }) != undefined;
}
let duplcateIndex = this.service.hasDataExist(this.list, 'xyz', value);
Вот еще одно краткое решение:
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>
Не нужно использовать lodash
, вы можете использовать следующий код:
function getDuplicates(array, key) {
return array.filter(e1=>{
if(array.filter(e2=>{
return e1[key] === e2[key];
}).length > 1) {
return e1;
}
})
}
Вы можете использовать counter
объект. Это будет иметь каждое число в качестве ключа и общее количество вхождений в качестве их значения. Вы можете использовать filter
чтобы получить числа, когда счетчик для номера становится 2
const array = [1, 1, 2, 2, 3],
counter = {};
const duplicates = array.filter(n => (counter[n] = counter[n] + 1 || 1) === 2)
console.log(duplicates)