【问题标题】:Javascript remove all occurrence of duplicate element, leaving the only one that is uniqueJavascript 删除所有出现的重复元素,只留下唯一的一个
【发布时间】:2014-12-16 14:41:47
【问题描述】:

我想删除多次出现的元素并获取唯一元素。数组总是有 3 个元素。 假设我有一个数组 [2,3,2],那么我需要得到 3,它仅在数组中是唯一的(删除两个 2,因为它们不止一次出现)。

我已尝试使用以下代码,但肯定无法按预期工作。

var firstArrTemp = [2,3,2];
var sorted_arr = firstArrTemp.sort();
var unique_element;
for (var i = 0; i < sorted_arr.length - 1; i++) {
    if (sorted_arr[i + 1] != sorted_arr[i]) {
        unique_element=sorted_arr[i];
    }
}

alert(unique_element);

谢谢!

【问题讨论】:

  • @Vohuman,不,这不是重复的,您引用的页面给出了 2,3 作为结果数组,我只想得到 3,同时删除两个 2。请在标记为重复之前仔细阅读问题
  • @vohuman:这不是这个问题所需要的。这个问题要求一个包含所有唯一元素的结果。
  • @Johan,这不是我想要的,请再看一遍帖子
  • 当数组为 [1,2,3] 时应该返回 [1,2,3] 怎么办?

标签: javascript arrays


【解决方案1】:

这应该可以解决问题:

Array.prototype.getUnique = function(){
    var uniques = [];
    for(var i = 0, l = this.length; i < l; ++i){
        if(this.lastIndexOf(this[i]) == this.indexOf(this[i])) {
            uniques.push(this[i]);
        }
    }
    return uniques;
}

// Usage:

var a = [2, 6, 7856, 24, 6, 24];
alert(JSON.stringify(a.getUnique()));

console.log(a.getUnique()); // [2, 7856]

要检查特定项在数组中是否唯一,它只检查找到的第一个索引是否与找到的最后一个索引匹配。

【讨论】:

  • 这就是确切的答案。谢谢哥们!
  • 这对于小型数组来说很好,但是如果您的数组有大量元素,这可能会变得很慢。
  • 我完全忘记了我在这里有答案。如果您知道更快的解决方案,请回答:-)
【解决方案2】:

filter() 函数的另一种选择:

var myArray = [1,2,3,2,2,4,3,7,3].sort();
var uniqueValues = myArray.filter(function(item, i, arr) {
  return (item !== arr[i-1] && item !== arr[i+1]);
});

其中uniqueValues = [1,4,7]

【讨论】:

  • 当然,这行得通。但是,对数组进行排序然后再次对其进行迭代似乎是双重工作。
  • 我不确定我是否完全正确地创建了性能测试用例(至少我尝试过),但结果如下:jsperf.com/remove-uniques。没有证明什么,但我没有看到先排序然后过滤一个真正的问题(或作为双重工作)。
【解决方案3】:

到目前为止,其他答案都具有O(n log n) 时间复杂度或更糟。这可以在 O(n) 时间内完成,尽管使用集合(Set.has 具有 O(1) 复杂性)而不是嵌套循环:

// .sort has complexity O(n log n): it's not needed here, avoid it
const getOnlyUniques = (arr) => {
  const foundOnce = new Set();
  const foundTwice = new Set();
  arr.forEach((item) => {
    if (foundOnce.has(item)) {
      foundTwice.add(item);
    }
    foundOnce.add(item);
  });
  return arr.filter(item => !foundTwice.has(item));
};
console.log(getOnlyUniques([2, 3, 2]));

【讨论】:

    【解决方案4】:

    在从数组中删除重复项时,我通常使用一种方法:

    const arrWithDuplicates = [1,2,2,2,3,4,4]
    const arrWithUniqueValues = [...new Set(arrWithDuplicates)]
    
    // result will be: [1,2,3,4]
    

    这也适用于字符串和布尔值。

    【讨论】:

    • 请更清楚地说明什么是Set
    • “Set 对象允许您存储任何类型的唯一值,无论是原始值还是对象引用。” - MDN 文档。
    • 因此它使您可以默认存储唯一值。
    【解决方案5】:

    另一种选择:

    var a = [2,3,2], result = [];
    
    for(var i = 0; i < a.length; i++){
    
        if(getAllIndexes(a, a[i]).length === 1)
            result.push(a[i]);
    }
    
    console.log(result);
    
    function getAllIndexes(arr, val) {
        var indexes = [], i = -1;
        while (~(i = arr.indexOf(val, i+1)))
            indexes.push(i);
        return indexes;
    }
    

    【讨论】:

    • 我不知道这里发生了什么 o.O 您是否对数组进行了两次迭代?
    • @Cerbrus 嘿,我并没有说它是性能最好的解决方案——只是一种替代方案;)虽然它很难产生
    • O(n) 是可能的,尽管使用了集合。 (也可以用对象来完成,但集合更合适)
    【解决方案6】:
    const nums = [1,2,3,3,3,5,5,5];
    const chars = ['a','b','a','b','a','a'];
    const mixed = [1,3,'b',3,'b','a','b',3];
    const unique = [1,'a',3]; 
    
    const distinct = (arr) => arr.filter((el) => arr.filter((item) => item === el).length === 1);
    
    console.log(distinct(nums)); // [ 1, 2 ]
    console.log(distinct(chars)); // []
    console.log(distinct(mixed)); // [ 1, 'a' ]
    console.log(distinct(unique)); // [ 1, 'a', 3 ]
    
    1. 首先,我们将使用“过滤器”对“arr”进行双重循环

    arr.filter((el) => arr.filter((item) => ... );

    1. 如果“item”等于“el”,则返回它的“length”

    arr.filter((el) => arr.filter((item) => item === el).length

    • 这将返回数组中每个元素的出现次数
    • 让我们用第一个例子来说明这一点:
    • [1,2,3,3,3,5,5,5] --> [1,1,3,3,3,3,3,3]
    • 1 发生 1 次
    • 2 发生 1 次
    • 3 次发生 3 次
    • 5 发生 3 次
    1. 要返回任何不重复或唯一的元素,我们只需指定长度等于“1”

    arr.filter((el) => arr.filter((item) => item === el).length === 1)

    • 此方法允许您从要返回的元素中选择出现次数
    • 例如,如果您想从数组中返回出现 3 次的元素,则将“长度”设置为等于 3

    【讨论】:

      【解决方案7】:

      另一种方法是采用Map 并将值设置为false,如果之前已经看到过一个键。然后通过取地图的值来过滤数组。

      var array = [2, 3, 2],
          result = array.filter(
              Map.prototype.get,
              array.reduce((m, v) => m.set(v, !m.has(v)), new Map)
          );
      
      console.log(result); // [3]

      【讨论】:

        【解决方案8】:

        只有一行

        arr.filter((item, pos, a) => a.lastIndexOf(item) === a.indexOf(item));
        

        const arr = [1, 2, 3, 4, 1, 5, 6, 5];
        const unique = arr.filter((item, pos, a) => a.lastIndexOf(item) === a.indexOf(item));
        console.log(unique);

        实用功能

        Array.prototype.unique = function() {
            return this.filter((item, pos, a) => a.lastIndexOf(item) === a.indexOf(item));
        }
        
        console.log([1, 2, 3, 4, 1, 5, 6, 5].unique());

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-03
          • 2021-04-15
          • 2022-11-03
          • 2019-05-01
          • 2021-12-28
          相关资源
          最近更新 更多