将 lodash _.uniqBy() 转换为原生 javascript
Converting lodash _.uniqBy() to native javascript
在这个片段中,我卡在了 _.uniqBy(array,iteratee)
,这个
iteratee
可以同时是函数或字符串
- 在什么地方放置检查唯一性的条件 属性 因为 itratee 函数可以是任何东西
var sourceArray = [ { id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
{ id: 1, name: 'bill' } ,
{id: 2,name: 'silly'},
{id: 2,name: 'billy'}]
function uniqBy (inputArray, callback) {
return inputArray.filter(callback)
}
var inputFunc = function (item) {
return item.name
}
// var destArray = _.uniqBy(sourceArray,'name')
var destArray = uniqBy(sourceArray, inputFunc)
console.log('destArray', destArray)
我们将不胜感激。
您可以使用按名称排序的排序和基于邻域比较的过滤器,如下所示:
var sourceArray = [ { id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
{ id: 1, name: 'bill' } ,
{id: 2,name: 'silly'},
{id: 2,name: 'billy'}]
var uniqBy = (inputArray, callback) => inputArray.sort((a,b) => callback(a) > callback(b))
.filter((x,i,arr) => i === arr.length -1 ? true : callback(x) !== callback(arr[i+1]));
var inputFunc = item => item.name;
var destArray = uniqBy(sourceArray, inputFunc)
console.log('destArray', destArray)
ES6 uniqBy
使用 Map
复杂度为 O(n):
const uniqBy = (arr, predicate) => {
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
return [...arr.reduce((map, item) => {
const key = (item === null || item === undefined) ?
item : cb(item);
map.has(key) || map.set(key, item);
return map;
}, new Map()).values()];
};
const sourceArray = [
{ id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
null,
{ id: 1, name: 'bill' } ,
{ id: 2,name: 'silly'},
{ id: 2,name: 'billy'},
null,
undefined
];
console.log('id string: ', uniqBy(sourceArray, 'id'));
console.log('name func: ', uniqBy(sourceArray, (o) => o.name));
我是 运行 我在 Create React App 中通过 Webpack 编写的代码,它必须使用 polyfill 来传播使用切片。这是我所做的,@oridori 答案的变体:
const uniqBy = (arr: any[], predicate: (item: any) => string) => {
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
const result = [];
const map = new Map();
arr.forEach((item) => {
const key = (item === null || item === undefined) ? item : cb(item);
if (!map.has(key)) {
map.set(key, item);
result.push(item);
}
});
return result;
};
重构并删除了@ori-drori 的解决方案
undefined
null
- 混合数组中的额外数字
- return
[]
如果第一个参数不是 Array
const uniqBy = (arr, predicate) => {
if (!Array.isArray(arr)) { return []; }
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
const pickedObjects = arr
.filter(item => item)
.reduce((map, item) => {
const key = cb(item);
if (!key) { return map; }
return map.has(key) ? map : map.set(key, item);
}, new Map())
.values();
return [...pickedObjects];
};
const a = [
12,
undefined,
{ id: 1, name: 'bob' },
null,
{ id: 1, name: 'bill' },
null,
undefined
];
const b = [
12,
{ id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
];
uniqBy(a, 'name');
uniqBy(b, Math.floor);
uniqBy([2.1, 1.2, 2.3], Math.floor);
在这个片段中,我卡在了 _.uniqBy(array,iteratee)
,这个
iteratee
可以同时是函数或字符串- 在什么地方放置检查唯一性的条件 属性 因为 itratee 函数可以是任何东西
var sourceArray = [ { id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
{ id: 1, name: 'bill' } ,
{id: 2,name: 'silly'},
{id: 2,name: 'billy'}]
function uniqBy (inputArray, callback) {
return inputArray.filter(callback)
}
var inputFunc = function (item) {
return item.name
}
// var destArray = _.uniqBy(sourceArray,'name')
var destArray = uniqBy(sourceArray, inputFunc)
console.log('destArray', destArray)
我们将不胜感激。
您可以使用按名称排序的排序和基于邻域比较的过滤器,如下所示:
var sourceArray = [ { id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
{ id: 1, name: 'bill' } ,
{id: 2,name: 'silly'},
{id: 2,name: 'billy'}]
var uniqBy = (inputArray, callback) => inputArray.sort((a,b) => callback(a) > callback(b))
.filter((x,i,arr) => i === arr.length -1 ? true : callback(x) !== callback(arr[i+1]));
var inputFunc = item => item.name;
var destArray = uniqBy(sourceArray, inputFunc)
console.log('destArray', destArray)
ES6 uniqBy
使用 Map
复杂度为 O(n):
const uniqBy = (arr, predicate) => {
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
return [...arr.reduce((map, item) => {
const key = (item === null || item === undefined) ?
item : cb(item);
map.has(key) || map.set(key, item);
return map;
}, new Map()).values()];
};
const sourceArray = [
{ id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
null,
{ id: 1, name: 'bill' } ,
{ id: 2,name: 'silly'},
{ id: 2,name: 'billy'},
null,
undefined
];
console.log('id string: ', uniqBy(sourceArray, 'id'));
console.log('name func: ', uniqBy(sourceArray, (o) => o.name));
我是 运行 我在 Create React App 中通过 Webpack 编写的代码,它必须使用 polyfill 来传播使用切片。这是我所做的,@oridori 答案的变体:
const uniqBy = (arr: any[], predicate: (item: any) => string) => {
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
const result = [];
const map = new Map();
arr.forEach((item) => {
const key = (item === null || item === undefined) ? item : cb(item);
if (!map.has(key)) {
map.set(key, item);
result.push(item);
}
});
return result;
};
重构并删除了@ori-drori 的解决方案
undefined
null
- 混合数组中的额外数字
- return
[]
如果第一个参数不是Array
const uniqBy = (arr, predicate) => {
if (!Array.isArray(arr)) { return []; }
const cb = typeof predicate === 'function' ? predicate : (o) => o[predicate];
const pickedObjects = arr
.filter(item => item)
.reduce((map, item) => {
const key = cb(item);
if (!key) { return map; }
return map.has(key) ? map : map.set(key, item);
}, new Map())
.values();
return [...pickedObjects];
};
const a = [
12,
undefined,
{ id: 1, name: 'bob' },
null,
{ id: 1, name: 'bill' },
null,
undefined
];
const b = [
12,
{ id: 1, name: 'bob' },
{ id: 1, name: 'bill' },
];
uniqBy(a, 'name');
uniqBy(b, Math.floor);
uniqBy([2.1, 1.2, 2.3], Math.floor);