【问题标题】:How to remove repeated entries from an array while preserving non-consecutive duplicates?如何在保留非连续重复项的同时从数组中删除重复项?
【发布时间】:2018-07-12 04:06:42
【问题描述】:

我有一个像var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5]; 这样的数组,我真的希望输出是[5,2,9,4,5]。我的逻辑是:

  • 一个一个地遍历所有元素。
  • 如果元素与前一个元素相同,则计算元素并执行newA = arr.slice(i, count)之类的操作
  • 新数组应该只填充相同的元素。
  • 对于我的示例输入,前 3 个元素是相同的,因此 newA 将类似于 arr.slice(0, 3)newB 将是 arr.slice(3,5) 等等。

我试着把它变成下面的代码:

function identical(array){
    var count = 0;
    for(var i = 0; i < array.length -1; i++){
        if(array[i] == array[i + 1]){
            count++;
            // temp = array.slice(i)
        }else{
            count == 0;
        }
    }
    console.log(count);
}
identical(arr);

我在弄清楚如何输出一个表示数组中相同的一组元素的元素时遇到了问题。如果元素不相同,则应按其在原始数组中的顺序输出。

【问题讨论】:

  • 你能给个jsfiddle.net吗?
  • 你为什么要对数组进行切片?
  • “输出代表一组元素的元素”是什么意思?您可以轻松删除重复,但这与“输出”有什么关系?也许您想要一个跟踪重复的数据结构,尽管原始数组已减少?
  • 那么预期的输出:[5,2,9,4,5][[5, 5, 5], [2, 2, 2, 2, 2], 9, 4, [5, 5, 5]] 或其他什么?
  • @Grundy [5,2,9,4,5]...我想切片,因为我不知道如何拆分相同的部分,以便获得数字跨度>

标签: javascript arrays


【解决方案1】:

使用array.filter(),您可以检查每个元素是否与之​​前的元素相同。

类似这样的:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

var b = a.filter(function(item, pos, arr){
  // Always keep the 0th element as there is nothing before it
  // Then check if each element is different than the one before it
  return pos === 0 || item !== arr[pos-1];
});

document.getElementById('result').innerHTML = b.join(', ');
&lt;p id="result"&gt;&lt;/p&gt;

【讨论】:

  • 我不确定退货声明。您将左侧的索引 pos 设置为 0。在右侧,您检查第一次迭代的项目是否不等于 arr[0-1],然后遍历数组 [1-1], [2-1]等用过滤法?这对我来说太先进了。我认为 arr[-1] 是未定义的。
  • @user2537537:我没有设置任何东西。 pos === 0 是一个比较。它正在检查pos 是否等于0。如果是,则将其添加到新数组中。 (它假定0 应该在新数组中,因为arr[-1] 未定义。)如果pos 大于0,则评估OR (||) 语句的另一侧。 item !== arr[pos-1] 检查数组中的当前项是否与前一项不同。如果是,则将其添加到新数组中,否则将被跳过。
  • a.filter() 遍历每个元素并运行回调。它将元素的值、它的索引(以及整个数组)作为参数传递给回调函数。
【解决方案2】:

如果你只是通过算法而不使用任何函数来查看

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];

    function identical(array){

        var newArray = [];
        newArray.push(array[0]);
        for(var i = 0; i < array.length -1; i++) {
            if(array[i] != array[i + 1]) {
                newArray.push(array[i + 1]);
            }
        }
        console.log(newArray);
    }
    identical(arr);

Fiddle;

【讨论】:

    【解决方案3】:

    reduce 的另一种方式

    var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
    
    var result = arr.reduce(function(acc, cur) {
      if (acc.prev !== cur) {
        acc.result.push(cur);
        acc.prev = cur;
      }
      return acc;
    }, {
      result: []
    }).result;
    
    
    document.getElementById('d').innerHTML = JSON.stringify(result);
    &lt;div id="d"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案4】:

      有点老套,但是,见鬼,我喜欢它。

      var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
      var arr2 = arr.join().replace(/(.),(?=\1)/g, '').split(',');
      

      给你

      [5,2,9,4,5]
      

      诚然,如果您使用多个字符的子字符串,这会失败,但只要不是这种情况,这应该可以正常工作。

      【讨论】:

      • 也许如果您将(.) 替换为(^,)+(匹配除逗号之外的所有内容),它也应该适用于多字符匹配和子字符串。直到我测试它才真正知道,但我现在太懒了:)
      • 必须喜欢无法解释的反对票。 @pid - 也许你是对的,我有点懒得去检查了。
      • Regex 是适合这项工作的错误工具。你的一个班轮是迄今为止最难理解的。在这个简单的例子中,它似乎只有about half as fast - 使用更短的 13 元素输入数组,它仍然比@Amit.rk3 发布的最简单的数组扫描慢 75%。用 Firefox 38 和 Chrome 43 测试;奇怪的是,过滤器比 Firefox 上的正则表达式慢,但 forloop 始终以很大的优势击败所有其他过滤器。
      • 也许你错过了我的附带条件:“有点老套,但是,见鬼,我喜欢它。”我从来没有说过这是最佳解决方案,只是“一个”解决方案,所以冷静。
      【解决方案5】:

      试试这个:

      var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4, 5, 5, 5];
      
      uniqueArray = a.filter(function(item, pos) {
      return a.indexOf(item) == pos;
      });
      

      Remove Duplicates from JavaScript Array

      【讨论】:

      • 不完全。这将导致[5, 2, 9, 4]。 OP 只想删除“本地”重复项以获得[5, 2, 9, 4, 5] 的结果。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-03
      • 2022-01-23
      相关资源
      最近更新 更多