获取数组中的所有唯一值(删除重复项)fot nest array / object

时间:2018-05-30 06:33:32

标签: javascript arrays node.js unique

我知道有很多独特数组的答案

但它们无法处理数组

我想要的是

源数组

[
    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是regexp时它有一个bug

4 个答案:

答案 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; }