【问题标题】:remove all elements that occur more than once from array [duplicate]从数组中删除所有多次出现的元素[重复]
【发布时间】:2019-04-03 15:28:27
【问题描述】:

在人们认为这与 Stack Overflow 上关于删除重复项的所有其他答案相同之前,您能否查看返回的内容而不是我想要做的事情。

我想删除所有多次出现的元素。我尝试了以下方法:

const a = ['Ronaldo', 'Pele', 'Maradona', 'Messi', 'Pele'];

const uniqueArray = a.filter(function(item, pos) {
  return a.indexOf(item) == pos;
})

console.log(uniqueArray)

我希望我的uniqueArray 成为

['Ronaldo', 'Maradona', 'Messi'];

【问题讨论】:

  • 包含Pele。仔细看
  • 嗯,好吧,所以你想删除所有多次出现的元素......
  • 是的,@JonasWilms 更新了问题,因为它可能不是很清楚

标签: javascript ecmascript-6


【解决方案1】:

简而言之:如果元素第一次出现的位置 (indexOf) 也是该元素在数组中的最后位置 (lastIndexOf),则保留该值。

如果索引不相等,则该值是重复的,您可以丢弃它。

const a = ['Ronaldo', 'Pele', 'Maradona', 'Messi', 
           'Pele', 'Messi', 'Jair', 'Baggio', 'Messi', 
           'Seedorf'];

const uniqueArray = a.filter(function(item) {
  return a.lastIndexOf(item) == a.indexOf(item);
});

console.log(uniqueArray);
/* output:  ["Ronaldo", "Maradona", "Jair", "Baggio", "Seedorf"] */

Codepen Demo

【讨论】:

  • 我将不得不为您添加巴乔投赞成票:-D
  • 并且考虑到巴乔在他职业生涯的大部分时间里只用一条腿完成了他所做的一切。
  • 请注意,对于长数组,这是非常低效的(二次比较),尽管对于 ES
【解决方案2】:

您可以计算每次迭代中的项目,以便将其包含在条件中:

const a = ['Ronaldo', 'Pele', 'Maradona', 'Messi', 'Pele'];

const uniqueArray = a.filter(function(item, pos) {
  var c = a.filter(i => i==item).length;
  return a.indexOf(item) == pos && c <= 1;
})

console.log(uniqueArray);

虽然更好的解决方案是将当前数组项的索引与Array.prototype.indexOf()Array.prototype.lastIndexOf() 进行比较:

const a = ['Ronaldo', 'Pele', 'Maradona', 'Messi', 'Pele'];

const uniqueArray = a.filter(function(item, pos) {
  return a.indexOf(item) === a.lastIndexOf(item);
})

console.log(uniqueArray);

【讨论】:

    【解决方案3】:

    您可以使用Map 来计算每个条目出现的次数,然后只选取只出现一次的条目。

    const a = ['Ronaldo', 'Pele', 'Maradona', 'Messi', 'Pele'];
    
    const uniqueArray = onlyUniqueItems(a);
    
    console.log(uniqueArray)
    
    
    function onlyUniqueItems(array) {
      const map = new Map();
      const result = [];
      
      array.forEach(item => {
        let amount = map.get(item) || 0;
        map.set(item, ++amount); //pre-increment and then set the amount
      });
      
      map.forEach((amount, item) => {
        if (amount == 1) {
          result.push(item);
        }
      });
      
      return result;
    }

    这将在 O(2n) 中运行,因为您最多必须进行两次扫描。您可以使用普通对象并在其上设置键值来实现类似的结果,但 Map 具有保留您拥有的项目类型的优势,而普通对象会将所有键转换为字符串:

    const a = [1, 2, 3, 3, "4", "4", "5"];
    
    const uniqueArray = onlyUniqueItems(a);
    const uniqueArrayUsingObject = onlyUniqueItemsUsingObject(a);
    
    console.log(uniqueArray)
    console.log(uniqueArrayUsingObject)
    
    
    function onlyUniqueItems(array) {
      const map = new Map();
      const result = [];
      
      //count occurences
      array.forEach(item => {
        let amount = map.get(item) || 0;
        map.set(item, ++amount); //pre-increment and then set the amount
      });
      
      //extract only the items that show once
      map.forEach((amount, item) => {
        if (amount == 1) {
          result.push(item);
        }
      });
      
      return result;
    }
    
    
    function onlyUniqueItemsUsingObject(array) {
      const map = {};
      const result = [];
      
      //count occurences
      array.forEach(item => {
        let amount = map[item] || 0;
        map[item] = ++amount; //pre-increment and then set the amount
      });
      
      //extract only the items that show once
      Object.entries(map).forEach(([item, amount]) => {
        if (amount == 1) {
          result.push(item);
        }
      });
      
      return result;
    }

    【讨论】:

      【解决方案4】:

      天真的方法是检查不止一次出现:

         a.filter((el, i) => !(a.indexOf(el) !== i || a.indexOf(el, i) > -1)));
      

      或者更复杂的有多个集合(但 O(n)):

        const found = new Set, values = new Set;
      
        for(const el of a)
         if(!found.has(el)) {
           found.add(el);
           values.add(el);
         } else if(values.has(el) {
           values.delete(el);
         }
       }
      
       const result = [...values.values()];
      

      【讨论】:

        【解决方案5】:

        为什么不使用Set

        const theSet = new Set(a);
        const values = set.values();
        const uniqueArray = Array.from(values);
        

        【讨论】:

        • 因为 OP 想要完全忽略重复值 - 如果一个值有重复项,则根本不要包含它。
        猜你喜欢
        • 1970-01-01
        • 2020-05-08
        • 2020-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 2016-12-08
        • 2017-04-12
        相关资源
        最近更新 更多