【问题标题】:Removing duplicates in an ordered array删除有序数组中的重复项
【发布时间】:2017-07-30 15:44:51
【问题描述】:

我要做的是找出数组元素在数组中重复的次数,将元素连同它在对象中的重复次数一起推送,然后删除元素及其所有重复项。

目前我有这个功能:

function getDuplicates(arr) {
  let lastIndex = null;
  let obj = {};
  for ( let i = 0; i < arr.length; i++ ) {
    lastIndex = arr.lastIndexOf(arr[i]);
    obj[arr[i]] = lastIndex + 1;
    arr.splice(0, lastIndex + 1 );
  }
  console.log(obj);
}

getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

哪些日志:{ '1': 4, '2': 2, '3': 4, '5': 5 }

它对前 3 个数字(1,2 和 3)效果很好,但 4 不显示,5 搞砸了,6 由于 lastIndex +1 而没有显示。我错过了什么还是有更好的方法来做到这一点?

谢谢。

【问题讨论】:

标签: javascript arrays sorting duplicates


【解决方案1】:

您可以简化很多逻辑。只是一个要计数的对象和一个用于递增值或定义为 1(如果未定义)的 if 语句。

function countDuplicates(arr) {
  // Contains a pair of values an instances.
  var counting = {};
  // Iterate array: check if already counted. If yes, increment, if not define as 1.
  for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1;
  console.log(counting);
  return counting;
}

countDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

补充一下,如果你也想获取独特的元素,你可以使用E6 set

var set = new Set([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

【讨论】:

  • 我喜欢函数背后的逻辑,但我不明白for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1; 的语法。你能用基本的javascript解释一下吗?
  • 知道了,它会变成这样:for ( let i = 0; i &lt; arr.length; i++ ) { if ( obj[arr[i]] ) { obj[arr[i]]++; } else { obj[arr[i]] = 1; } }
  • 正确!混合你的结构和我的名字:)for (let i = 0; i &lt; arr.length; i++) { var el = arr[i]; if (counting[el]) { counting[el]++ } else { counting[el] = 1; } }我这样做是为了让代码变小:)
  • 有趣的是,如果我使用未排序的数组,它仍然有相同的结果。你能解释一下为什么它把对象键按顺序排列(从小到大)吗?
  • 那是因为我们使用数字作为索引。因此,顺序始终为 0、1、2... 即使您将它们转换为字符串,它也会以数字形式思考并排序索引。但是,如果您尝试:countDuplicates(['b', 'c', 'a']);,它不会订购它们。如果你想保持它们的出现顺序并保持代码简单,你可以在 el 的开头添加 n:for (el of arr) { el = 'n'+el; (counting[el]) ? counting[el]++ : counting[el] = 1; } 但是你会有 n5 而不是 5 等等。
【解决方案2】:

您可以像这样计算和打印:

function getDuplicates(arr) {
    var counts = {};
    arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
    console.log(counts);
}

【讨论】:

    【解决方案3】:
    function getDuplicates(arr) {
      let lastNum = null;
      let obj = {};
      for ( let i = 0; i < arr.length; i++ ) {
        if (arr[i] != lastNum){
          lastNum = arr[i];
          obj[arr[i]] = 1;
        }else{
          obj[arr[i]]++;
        }
      }
      console.log(obj);
    }
    

    【讨论】:

      【解决方案4】:

      您可以简单地使用Array#reduce() 来计算出现次数,并使用Array#filter() 来删除重复项

      getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
      
      function getDuplicates(arr) {
        var obj = arr.reduce((map, item) => (map[item] = ++map[item] || 1, map),{} );
        var withoutDup = arr.filter((item, pos) => arr.indexOf(item) == pos);
      
        console.log(JSON.stringify(obj));
        console.log(JSON.stringify(withoutDup));
      }

      【讨论】:

        【解决方案5】:

        这是解决问题的一种方法。

        首先,我使用new Set() 删除了给定数组中的所有重复元素,然后使用Array#forEach 对其进行迭代,并使用Array#filter 检查给定元素在传递的数组中出现的次数。

        function getDuplicates(arr){
          var filtered = [...new Set(arr)],
              result = {};
              filtered.forEach(function(v){
                result[v] = arr.filter(c => c == v).length;
              })
              console.log(result);
        }
            
        getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);

        Array#reduce 解决方案。

        function getDuplicates(arr) {
          var res = arr.reduce(function(s, a) {
            s[a] = arr.filter(c => c == a).length;
            return s;
          }, {});
          console.log(res);
        }
        
        getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);

        【讨论】:

        • 我很欣赏这个答案,但我一直在寻找更多不使用 js 内置方法的“编程”解决方案。
        • @TudorApostol 你想学习 JS 吗?如果是这样 - 慢慢检查我的答案并学习。这些函数在纯 javascript 中内置。如果不了解它们,您将不会擅长 JS。所以学习兄弟,学习!
        【解决方案6】:

        您似乎想计算重复项,但如果您只想删除重复项(如标题所述),请按照@ChantryCargill 的建议:

        function removeDuplicates (arr) {
           var results = [];
           for(var i = 0; i < arr.length; i++) {
              var item = arr[i];
              if(results.indexOf(item) === -1) {
                 results.push(item);
              }
           }
           return results;
        }
        
        console.log(removeDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ])); 
        //[1, 2, 3, 4, 5, 6]
        

        如果要计算重复项:

        function getDuplicates(arr) {
           var results = {};
           for(var item of arr) {
              if(!results[item]) {
                 results[item] = 0;
              }
              results[item]++;
           }
           return results;
        }
        
        console.log(getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ])); 
        //{"1":4,"2":2,"3":4,"4":2,"5":3,"6":1}
        

        【讨论】:

        • "找出一个数组元素在数组中重复了多少次,将元素连同它的重复次数一起推送"
        • @Andreas "删除有序数组中的重复项"。
        【解决方案7】:

        试试这个:

        function getDuplicates(){
          var numbers=Array.prototype.slice.call(arguments);
          var duplicates={};
          for(var index in numbers){
            if(numbers.indexOf(numbers[index])==index)
              continue;
            duplicates[numbers[index]]= (duplicates[numbers[index]] || 0) + 1;
          }
          return duplicates;
        }
        
        console.log(getDuplicates(1,2,3,1,1,3,4,5,6,7,8,6));
        /*
        prints {
          1: 2,
          3: 1,
          6: 1
        }
        */

        【讨论】:

          猜你喜欢
          • 2021-03-02
          • 2016-10-01
          • 2016-01-24
          • 1970-01-01
          • 2019-07-11
          • 2012-03-10
          相关资源
          最近更新 更多