返回已过滤的对象数组

时间:2017-05-09 03:26:46

标签: javascript arrays filter duplicates

我正在努力从一系列物体中移除欺骗。我有一个数组,storedItems:

var storedItems = [
    {text: "1", checked: false },
    {text: "2", checked: false },
    {text: "3", checked: false },
    {text: "string", checked: false }
]

等。文本值是字符串或数字字符串。我可以在哈希值或uniqueVals中识别唯一的文本值...

filterDupes(storedItems);

function filterDupes(input) {
    var hash = {};
    var uniqueVals = [];
    input.forEach(obj => {
        hash[obj.text] = true;
    })
    var uniqueVals = Object.keys(hash); // Array
    return input.filter(function(obj, ix, arr) {
        uniqueVals.indexOf(obj.text) !== -1; // NOPE
    }) // .filter
} // filterDupes

...它是如何比较散列键或uniqueVals与输入数组对象,即我需要什么(w / out for for循环或另一个forEach?)来返回过滤后的数组,这让我抨击我的头撞墙,试图找到一些版本的返回哈希[obj.text] == obj.text;或者返回(hash.key === obj.text)

编辑:在这里摆弄:https://jsfiddle.net/WTFoxtrot/by3nhy4n/2/

2 个答案:

答案 0 :(得分:2)

使用Array.prototype.map()Array.prototype.filter()的组合:

let items = [
    {text: "1", checked: false},
    {text: "2", checked: false},
    {text: "3", checked: false},
    {text: "string", checked: false},
    {text: "2", checked: false},
    {text: "string", checked: false},
    {text: "1", checked: false}
];
let values = items.map(it => it.text).filter((v, i, a) => a.indexOf(v) === i);

console.log(values); // ["1", "2", "3", "string"]

过滤器闭包(v, i, a) => a.indexOf(v) === i过滤掉除第一次出现该值以外的任何位置的所有值。

使用相同的原则,如果您想过滤对象数组本身而不是返回唯一值列表,可以将Array.prototype.filter()Array.prototype.find()一起使用:

let items = [
    {text: "1", checked: false},
    {text: "2", checked: false},
    {text: "3", checked: false},
    {text: "string", checked: false},
    {text: "2", checked: false},
    {text: "string", checked: false},
    {text: "1", checked: false}
];
let filtered = items.filter((x, i, a) => a.find(y => x.text === y.text) === x);

console.log(filtered); // [{"text": "1", "checked": false}, {"text": "2", "checked": false}, {"text": "3", "checked": false}, {"text": "string", "checked": false}]

答案 1 :(得分:2)

V2:使用Set对象,你可以用同样的方式使用数组index:

function filterDupes(input) {
  var unique = new Set();

  return input.filter((obj, ix, arr) => {
    if(!unique.has(obj.text)) {
       unique.add(obj.text);
       return true;
    }
    return false;
  })
}

如果你不想过多地改变你的功能:

...
return input.filter((obj, ix, arr) => {
    var index = uniqueVals.indexOf(obj.text);
    if(index !== -1) {
    // Remove the element from unique array
       uniqueVals.splice(index,1);
       return true;
    }
    return false;
})

V1:不正确。 以前,你的功能有点不对劲。它实际上什么也没做。您只需将文本推送到数组,然后再次检查该数组中是否存在文本。

var storedItems = [
  {text: "1", checked: false },
  {text: "2", checked: false },
  {text: "3", checked: false },
  {text: "string", checked: false }
];

function filterDupes(input) {
  //Your previous code inside function
  ...
  return input.filter(function(obj, ix, arr) {
     return uniqueVals.indexOf(obj.text) !== -1;
  })
}