lodash:从数组中获取重复值

问题描述 投票:0回答:13

假设我有一个像这样的数组:

[1, 1, 2, 2, 3]

我想获得这种情况下的重复项:

[1, 2]

lodash支持这个吗?我想以尽可能短的方式做到这一点。

javascript arrays lodash
13个回答
56
投票

您可以使用这个:

_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1))

或者不使用 lodash,您可以使用纯 JavaScript:

arr.filter((val, i) => arr.includes(val, i + 1))

注意:如果一个数字在数组中出现两次以上,您可以随时使用

_.uniq


35
投票

另一种方法是按唯一项进行分组,并返回具有超过 1 个项的组键

_([1, 1, 2, 2, 3]).groupBy().pickBy(x => x.length > 1).keys().value()

18
投票
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})));

这也适用于未排序的数组。


6
投票

另一种方式,但使用过滤器和 ecmaScript 2015 (ES6)

var array = [1, 1, 2, 2, 3];

_.filter(array, v => 
  _.filter(array, v1 => v1 === v).length > 1);

//→ [1, 1, 2, 2]

6
投票

先使用

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]

http://jsbin.com/panama/edit?js,控制台


6
投票

纯JS解决方案:

export function hasDuplicates(array) {
  return new Set(array).size !== array.length
}

对于对象数组:

/**
 * 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;
};

3
投票

这是另一个简洁的解决方案:

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
负责处理
_.filter
回来的配音。

与 ES6 相同,设置

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))


1
投票

你可以使用这段代码,它的速度要快得多,因为它的复杂度为 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]

1
投票

这是我的,类似于 es6,无依赖的答案。用过滤器代替减速器

// 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 :)


1
投票

您可以使用

counter
对象。这将把每个数字作为键,将出现的总数作为它们的值。当数字计数器变为 2 时,您可以使用
filter
来获取数字

const array = [1, 1, 2, 2, 3],
      counter = {};
      
const duplicates = array.filter(n => (counter[n] = counter[n] + 1 || 1) === 2)

console.log(duplicates)


0
投票

希望以下解决方案对您有所帮助,并且在所有情况下都会有用

  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);

0
投票

无需使用

lodash
,您可以使用以下代码:

function getDuplicates(array, key) {
  return array.filter(e1=>{
    if(array.filter(e2=>{
      return e1[key] === e2[key];
    }).length > 1) {
      return e1;
    }
  })
}

-7
投票

为什么不只使用这个?

_.uniq([4, 1, 5, 1, 2, 4, 2, 3, 4]) // [4, 1, 5, 2, 3]
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.