获取嵌套数组/对象的数组中的所有唯一值(删除重复项)
Posted
技术标签:
【中文标题】获取嵌套数组/对象的数组中的所有唯一值(删除重复项)【英文标题】:Get all unique values in an array (remove duplicates) fot nest array / object 【发布时间】:2018-11-08 21:38:26 【问题描述】:我知道唯一数组有很多答案
但他们无法处理数组数组
我想要的是
源数组
[
1,
0,
true,
undefined,
null,
false,
['a', 'b', 'c'],
['a', 'b', 'c'],
['a', 'c', 'b'],
a: b: 2 ,
a: b: 2 ,
a: b: 3 ,
a: b: undefined ,
a: ,
a: b: 3, c: undefined ,
]
回报
[
1,
0,
true,
undefined,
null,
false,
['a', 'b', 'c'],
['a', 'c', 'b'],
a: b: 2 ,
a: b: 3 ,
a: b: undefined ,
a: ,
a: b: 3, c: undefined ,
]
arr-unique 可以处理object[],但是不能处理数组数组
设置不能太
失败代码
console.log(array_unique(data));
console.log([...new Set(data)]);
console.log(data.filter(function (el, index, arr)
return index == arr.indexOf(el);
));
====================
更新
我为此 array-hyper-unique 创建了一个模块,但没有使用 json stringify,因为当 valuse 为正则表达式时它有一个错误
【问题讨论】:
是['a', 'b', 'c']
和['a', 'c', 'b']
一样吗?
@Eddie 不一样
【参考方案1】:
一种简单的方法是stringify
数组和对象以识别重复项:
const input = [
1,
true,
['a', 'b', 'c'],
['a', 'b', 'c'],
a: b: 2 ,
a: b: 2 ,
a: b: 3 ,
a: b: 3, c: undefined ,
];
const outputSet = new Set();
const stringifiedObjs = new Set();
input.forEach(item =>
if (typeof item !== 'object') outputSet.add(item);
else
// replace undefineds with something, else they'll be ignored by JSON.stringify:
const stringified = JSON.stringify(
item,
(k, v) => v === undefined ? 'undefined-value' : v
);
if (!stringifiedObjs.has(stringified))
outputSet.add(item);
stringifiedObjs.add(stringified)
);
console.log([...outputSet]);
【讨论】:
它适用于undefined
dupes 和 a: b: undefined ,
dupes,你在想什么?
试试console.log(JSON.stringify( a: b: undefined )); // "a":
缺少b
属性。
现在看来这是最好的答案【参考方案2】:
尝试使用JSON.stringify
将元素转换为字符串,并使用indexOf
将这些元素推送到另一个数组,前提是另一个数组不包含此元素。然后再次使用map
& JSON.parse
将字符串转换为原始格式
var data = [
1,
true, ['a', 'b', 'c'],
['a', 'b', 'c'],
a:
b: 2
,
a:
b: 2
,
a:
b: 3
,
]
// Create a new array of only string
// map will give new array and JSON.stringify will convert elements to string
var newData = data.map(function(item)
return JSON.stringify(item)
)
//An empty array which will contain only unique values
var uniques = [];
// loop over the array of stirngs and check
//if that value is present in uniques array
//if not then push the element
newData.forEach(function(item)
if (uniques.indexOf(item) === -1)
uniques.push(item)
);
//Convert array of string to json
var parsedArr = uniques.map(function(item)
return JSON.parse(item)
);
console.log(parsedArr)
【讨论】:
@NinaScholz 他修改了原始数组,后来添加了未定义的属性【参考方案3】:您的方法不起作用的原因是因为第一个['a', 'b', 'c']
和第二个['a', 'b', 'c']
是不同的对象, a: b: 2
的第一个和第二个实例也是如此。
因此,即使您将它们添加到 Set
,它们也会被视为彼此不等价,因此不会因唯一性而被过滤。
您似乎想根据每个对象的绝对值获得一个唯一的数组。一种简单的方法是像这样使用 ES6 Map
:
function uniq(arr)
var uniqMap = new Map()
arr.forEach(element =>
uniqMap.set(JSON.stringify(element), element)
)
return [...uniqMap.values()]
然后你就可以得到你想要的结果:
uniq(data)
//Result: [ 1, true, [ 'a', 'b', 'c' ], a: b: 2 , a: b: 3 ]
【讨论】:
看起来你的答案是最好的,如果没有未知的错误【参考方案4】:您可以对对象采用递归方法并检查值。
function check(a, b)
if (!a || typeof a !== 'object')
return a === b;
var keys = Object.keys(a);
return keys.length === Object.keys(b).length
&& keys.every(k => k in b && check(a[k], b[k]));
var array = [1, 0, true, undefined, null, false, ['a', 'b', 'c'], ['a', 'b', 'c'], ['a', 'c', 'b'], a: b: 2 , a: b: 2 , a: b: 3 , a: b: undefined , a: , a: b: 3, c: undefined ],
unique = array.reduce((r, b) => (r.some(a => check(a, b)) || r.push(b), r), []);
console.log(unique);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
以上是关于获取嵌套数组/对象的数组中的所有唯一值(删除重复项)的主要内容,如果未能解决你的问题,请参考以下文章