映射通过对象数组然后使用过滤器删除欺骗

时间:2017-05-26 21:43:55

标签: javascript arrays

所以我的问题是我是否有一个对象数组

var arr = [{"id":1, "image":"sport.jpg", "tag_name":"Sport","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":2, "image":"sport.jpg", "tag_name":"Fudbal","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":3,  "image":"sport.jpg","tag_name":"Premier League","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":4, "image":"sport.jpg", "tag_name":"La liga","tag_type":"Takmicenje","my_feed":true,"my_favourites":true},
{"id":5, "image":"sport.jpg", "tag_name":"Real Madrid","tag_type":"Fudabal","my_feed":true,"my_favourites":true},
{"id":6, "image":"sport.jpg","tag_name":"UEFA","tag_type":"Tim","my_feed":true,"my_favourites":true},
{"id":7,"image":"sport.jpg","tag_name":"Juve","tag_type":"Liga","my_feed":true,"my_favourites":false},
{"id":8,"image":"sport.jpg","tag_name":"Barca","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":9,"image":"sport.jpg","tag_name":"Sport","tag_type":"Fudbal","my_feed":true,"my_favourites":true}
]

我映射了数组然后过滤它以删除欺骗,(tag_type)但是我不能把头包住它。

var filtred = arr.map(function(item) { return item.tag_type;
  }).filter(function(filt,index) {
    return filt.indexOf(filt) == index;
});

过滤器的结果是[“Takmicenje”]

地图工作正常

["Takmicenje", "Takmicenje", "Takmicenje", "Takmicenje", "Fudabal", "Tim", "Liga", "Takmicenje", "Fudbal"]

过滤结果

["Takmicenje"]

我想获得

数组
['Takmicenje','Fudbal','Tim','Liga'];

5 个答案:

答案 0 :(得分:3)

以正确的方式使用过滤器:

var arr = [{"id":1, "image":"sport.jpg", "tag_name":"Sport","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":2, "image":"sport.jpg", "tag_name":"Fudbal","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":3,  "image":"sport.jpg","tag_name":"Premier League","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":4, "image":"sport.jpg", "tag_name":"La liga","tag_type":"Takmicenje","my_feed":true,"my_favourites":true},
{"id":5, "image":"sport.jpg", "tag_name":"Real Madrid","tag_type":"Fudabal","my_feed":true,"my_favourites":true},
{"id":6, "image":"sport.jpg","tag_name":"UEFA","tag_type":"Tim","my_feed":true,"my_favourites":true},
{"id":7,"image":"sport.jpg","tag_name":"Juve","tag_type":"Liga","my_feed":true,"my_favourites":false},
{"id":8,"image":"sport.jpg","tag_name":"Barca","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":9,"image":"sport.jpg","tag_name":"Sport","tag_type":"Fudbal","my_feed":true,"my_favourites":true}
];

var filtred = arr.map(function(item) { return item.tag_type;
  }).filter(function(filt, ind, currentArray) {
    return ind == currentArray.indexOf(filt);
});
console.log(filtred);

答案 1 :(得分:1)

答案:

答案#1 - 漂亮&动态:

 let result = [...new Set(arr.map(item=>item.tag_type))];

答案#2 - 快速(最高答案的5倍)

let tagTypes = {};
arr.forEach(item => tagTypes[item.tag_type] = true)
let result = Object.keys(tagTypes)

解释:

大多数现有答案都非常实用,特别是对于这个小型的数据集。当你有数以千计的项目要迭代时,问题就开始出现了,所以让我们谈谈性能。 到目前为止,每个响应都在某种循环中使用Array.prototype.indexOf。这个问题是indexOf本身就是一个循环。 结果,@ quirimmo的响应重复11次,@ SeanGregory的重复次数为10次。

下面,我将解释如何在没有嵌套循环的情况下实现所需的效果。

回答#1

让我们分开:

 let result = [...new Set(arr.map(item=>item.tag_type))]

在此中心,我们有map。这应该是熟悉的。

let allTagTypes = arr.map(item=>item.tag_type)

ES6 Set是一个可迭代对象,“允许您存储任何类型的唯一值,无论是原始值还是对象引用”。 这意味着当您构造一个Set,向它传递一个包含重复项的数组时,生成的Set将基本上删除重复项并仅存储每个项一次。 因此,我们可以执行以下操作并获取一组唯一标记类型:

let filteredTagTypes = new Set(allTagTypes);

这很好,但我们希望结果为数组,而不是集合。我们可以使用Spread Operator将此Set转换为数组。

let result = [...filteredTagTypes];
// ["Takmicenje","Fudabal","Tim","Liga","Fudbal"]

就是这样!

注意:问题是如何从属性值数组中过滤掉重复项。此解决方案适用于所有类型的值。对于提问者的特定场景(值始终是字符串),答案#2要好得多。

事实证明,Set的构造是一个相对繁重的过程。在性能方面,我们最终与indexOf大致相同。虽然这只是一个单行,但为什么不呢? :)

现在为numero dos!

回答#2

这个更简洁。

let tagTypes = {};
arr.forEach(item => tagTypes[item.tag_type] = true)
let result = Object.keys(tagTypes)

首先,我们创建一个将保存我们的标签类型的对象。

let tagTypes = {};

接下来,我们遍历数组中的每个项目。 对于每个项目,我们在tagTypes对象上设置了一个属性,其中包含项tag_name的键和值true。如果该物业已经存在,则只需用同样的东西覆盖。如果没有,则将其添加到对象中。

当循环完成时,tagTypes将是一个如下所示的对象:

{
     "Takmicenje":true,
     "Fudabal":true,
     "Tim":true,
     "Liga":true,
     "Fudbal":true
}

我们现在可以获得一个tagTypes'密钥使用Object.keys()。

let result = Object.keys(tagTypes)
// ["Takmicenje","Fudabal","Tim","Liga","Fudbal"]

那是两个次迭代。 Vroom vroom!

结果

如果您有兴趣,这是运行每个函数的代码段和JSPerf性能比较:

JSPerf:https://jsperf.com/unique-array-items-from-properties



let arr = [{"id":1, "image":"sport.jpg", "tag_name":"Sport","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":2, "image":"sport.jpg", "tag_name":"Fudbal","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":3,  "image":"sport.jpg","tag_name":"Premier League","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":4, "image":"sport.jpg", "tag_name":"La liga","tag_type":"Takmicenje","my_feed":true,"my_favourites":true},
{"id":5, "image":"sport.jpg", "tag_name":"Real Madrid","tag_type":"Fudabal","my_feed":true,"my_favourites":true},
{"id":6, "image":"sport.jpg","tag_name":"UEFA","tag_type":"Tim","my_feed":true,"my_favourites":true},
{"id":7,"image":"sport.jpg","tag_name":"Juve","tag_type":"Liga","my_feed":true,"my_favourites":false},
{"id":8,"image":"sport.jpg","tag_name":"Barca","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":9,"image":"sport.jpg","tag_name":"Sport","tag_type":"Fudbal","my_feed":true,"my_favourites":true}
];

function withSet(arr){ // Answer #1
	return [...new Set(arr.map(item=>item.tag_type))]
}

function withObject(arr){ // Answer #2
	let tagTypes = {};
	arr.forEach(item => tagTypes[item.tag_type] = true)
	return Object.keys(tagTypes)
}

console.log('With Object', withObject(arr))
console.log('With Set', withSet(arr))




注意:在问题中,它表示所需的结果为['Takmicenje','Fudbal','Tim','Liga'],但删除重复项的实际结果为[“Takmicenje", "Fudabal", "Tim", "Liga", "Fudbal"]

答案 2 :(得分:0)

看起来您只想要删除重复项的tag_type数组。你去吧

var arr = [{"id":1, "image":"sport.jpg", "tag_name":"Sport","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":2, "image":"sport.jpg", "tag_name":"Fudbal","tag_type":"Takmicenje","my_feed":true, "my_favourites":true},
{"id":3,  "image":"sport.jpg","tag_name":"Premier League","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":4, "image":"sport.jpg", "tag_name":"La liga","tag_type":"Takmicenje","my_feed":true,"my_favourites":true},
{"id":5, "image":"sport.jpg", "tag_name":"Real Madrid","tag_type":"Fudabal","my_feed":true,"my_favourites":true},
{"id":6, "image":"sport.jpg","tag_name":"UEFA","tag_type":"Tim","my_feed":true,"my_favourites":true},
{"id":7,"image":"sport.jpg","tag_name":"Juve","tag_type":"Liga","my_feed":true,"my_favourites":false},
{"id":8,"image":"sport.jpg","tag_name":"Barca","tag_type":"Takmicenje","my_feed":false,"my_favourites":true},
{"id":9,"image":"sport.jpg","tag_name":"Sport","tag_type":"Fudbal","my_feed":true,"my_favourites":true}
];

var filtered = arr.map(function(item) {
                      return item.tag_type;
                  })
                  .reduce(function(result, currentTagType) {
                      if (result.indexOf(currentTagType) === -1)
                          result.push(currentTagType);
                      return result;
                  }, []);

console.log(filtered);

答案 3 :(得分:0)

只需使用:

var filtred = arr.map(function(item) { return item.tag_type;
  }).filter(function(filt,index, mapped) { 
    return mapped.indexOf(filt) == index;
});

享受

答案 4 :(得分:-1)

https://jsperf.com/unique-array-items-from-properties-2/1

实施递归解决方案。相当快速。和ES6 has O(1) memory complexity for tail end recursion

使用indexOf递归

function recurse(arr, newArr){
  let el = arr.shift();
  if (el === undefined){
    return newArr;  
  }else{
    if (newArr.indexOf(el.tag_name) === -1){
      newArr.push(el.tag_name);
    }
    recurse(arr, newArr);
  }
}
recurse(arr, []);

使用对象的递归(基于mccallofthewild的回答)

  function withRecursionAndObject(arr, newObj){
    let el = arr.shift();
    if (el === undefined){
      return Object.keys(newObj);  
    }else{
      newObj[el.tag_type] = true;
      withRecursionAndObject(arr, newObj);
    }
  }

使用时间

let i = arr.length;
var filtered = [];
while(i--){
  if (filtered.indexOf(arr[i].tag_name) === -1){
    filtered.push(array[i].tag_name);
  }
}

https://jsperf.com/filter-vs-while-vs-lodash-vs-sort