我知道有很多独特数组的答案
但它们无法处理数组
我想要的是
源数组
[
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 } },
]
代码失败
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是regexp时它有一个bug
答案 0 :(得分:7)
一个简单的方法是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]);

答案 1 :(得分:3)
尝试使用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)
答案 2 :(得分:2)
您的方法不起作用的原因是因为第一个['a', 'b', 'c']
,第二个['a', 'b', 'c']
是不同的对象,{{的第一个和第二个实例也是如此1}}。
因此,即使您将它们添加到{ a: { b: 2 } }
,它们也会被视为彼此不相等,因此,不会针对唯一性进行过滤。
似乎你想根据每个对象的绝对值得到一个唯一的数组。一种简单的方法是使用ES6 Set
,如下所示:
Map
然后,您可以获得所需的结果:
function uniq(arr) {
var uniqMap = new Map()
arr.forEach(element => {
uniqMap.set(JSON.stringify(element), element)
})
return [...uniqMap.values()]
}
答案 3 :(得分:2)
您可以对对象采用递归方法并检查值。
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; }