lodash:从数组中获取重复值
lodash: Get duplicate values from an array
假设我有一个这样的数组:[1, 1, 2, 2, 3]
我想得到在这种情况下的重复项:[1, 2]
lodash支持吗?我想以最短的方式完成。
你可以使用这个:
_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1));
请注意,如果一个数字在您的数组中出现两次以上,您始终可以使用 _.uniq
。
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]
另一种方法是按唯一项进行分组,return 具有多个项的组键
_([1, 1, 2, 2, 3]).groupBy().pickBy(x => x.length > 1).keys().value()
好吧,您可以使用这段代码,它的复杂度为 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,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>
_.uniq
负责 _.filter
返回的配音。
与 ES6 相同 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))
无需使用lodash
,可以使用以下代码:
function getDuplicates(array, key) {
return array.filter(e1=>{
if(array.filter(e2=>{
return e1[key] === e2[key];
}).length > 1) {
return e1;
}
})
}
您可以使用 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)
纯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;
};
为什么不只使用这个?
_.uniq([4, 1, 5, 1, 2, 4, 2, 3, 4]) // [4, 1, 5, 2, 3]
假设我有一个这样的数组:[1, 1, 2, 2, 3]
我想得到在这种情况下的重复项:[1, 2]
lodash支持吗?我想以最短的方式完成。
你可以使用这个:
_.filter(arr, (val, i, iteratee) => _.includes(iteratee, val, i + 1));
请注意,如果一个数字在您的数组中出现两次以上,您始终可以使用 _.uniq
。
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]
另一种方法是按唯一项进行分组,return 具有多个项的组键
_([1, 1, 2, 2, 3]).groupBy().pickBy(x => x.length > 1).keys().value()
好吧,您可以使用这段代码,它的复杂度为 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,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>
_.uniq
负责 _.filter
返回的配音。
与 ES6 相同 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))
无需使用lodash
,可以使用以下代码:
function getDuplicates(array, key) {
return array.filter(e1=>{
if(array.filter(e2=>{
return e1[key] === e2[key];
}).length > 1) {
return e1;
}
})
}
您可以使用 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)
纯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;
};
为什么不只使用这个?
_.uniq([4, 1, 5, 1, 2, 4, 2, 3, 4]) // [4, 1, 5, 2, 3]