获取嵌套数组/对象的数组中的所有唯一值(删除重复项)

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; 

【讨论】:

以上是关于获取嵌套数组/对象的数组中的所有唯一值(删除重复项)的主要内容,如果未能解决你的问题,请参考以下文章

ES6方式 - 按键从嵌套数组中获取唯一值

从对象数组中的嵌套数组中删除重复项

按数组中的多个属性对对象进行分组,然后将它们的值相加

如何从包含 JavaScript 中重复项的数组中获取唯一值数组? [复制]

如何将 json 对象键转换为不同的数组来删除重复项

从 JS 数组中删除重复值 [重复]