js多对象数组唯一方法
Sep 13, 2016
前些天做项目, 小伙伴遇到一个js多对象数组, 求唯一问题, 思考了很久, 没有找到好的方案. 小伙伴使用了递归, 个人感觉不是最好的方案.
今天有空重写了一个.
原理分析
遍历数组中的对象, 第一个对象和接下来所有的对象进行对比, 如果碰到一致的, 将其删除. 自身对象进行处理.
问题主要处在删除后, 数组的索引发生变更, 之前没有考虑到. 一直不正确. 今天把代码贴出. 欢迎拍砖.! :)
es6 code 需要babeljs转换下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81// es6 code
const uniq = (source = [], fields = [], callback = ()=>{}) => {
for(let i = 0; i < source.length; i++){
for(let j = i+1; j < source.length; j++){
/*
* 对比对象中的字段(传入的参数)是否相等 返回一个和fileds数组相同数量的true, false数组,
* 本列子返回[false, true], 对返回的true, false数组reduce计算, 看看对象是否相等, 如果相等
* 调用callback, 删除原数组中相同的对象, 原数组相同的对象删除后, for循环需要回退.
*/
if(fields.map((field) => {
return source[i][field] == source[j][field];
}).reduce((prev, next) => prev&&next)){
source[i] = callback(source[i]);
source.splice(j, 1);
j--; // 回退for
}
}
}
return source;
};
let source = [
{name: 'luo', age: 3, count:1},
{name: 'v', age: 2, count:1},
{name: 'luo', age: 3, count:1},
{name: 'luo', age: 3, count:1},
{name: 'luo', age: 3, count:1},
{name: 'v', age: 2, count:1},
{name: 'luo', age: 3, count:1},
{name: 'v', age: 3, count:1},
{name: 'v', age: 2, count:1},
{name: 'v', age: 42, count:1},
];
let ret = uniq(source, ['name', 'age'], (item) => {
item.count += 1;
return item;
});
* es5 转换好的code
// es5 code
;
var uniq = function uniq() {
var source = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
var fields = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];
var callback = arguments.length <= 2 || arguments[2] === undefined ? function () {} : arguments[2];
var _loop = function _loop(i) {
var _loop2 = function _loop2(_j) {
if (fields.map(function (field) {
return source[i][field] == source[_j][field];
}).reduce(function (prev, next) {
return prev && next;
})) {
source[i] = callback(source[i]);
source.splice(_j, 1);
_j--;
}
j = _j;
};
for (var j = i + 1; j < source.length; j++) {
_loop2(j);
}
};
for (var i = 0; i < source.length; i++) {
_loop(i);
}
return source;
};
var source = [{ name: 'luo', age: 3, count: 1 }, { name: 'v', age: 2, count: 1 }, { name: 'luo', age: 3, count: 1 }, { name: 'luo', age: 3, count: 1 }, { name: 'luo', age: 3, count: 1 }, { name: 'v', age: 2, count: 1 }, { name: 'luo', age: 3, count: 1 }, { name: 'v', age: 3, count: 1 }, { name: 'v', age: 2, count: 1 }, { name: 'v', age: 42, count: 1 }];
var ret = uniq(source, ['name', 'age'], function (item) {
item.count += 1;
return item;
});
//console.log(ret)