获取数组中的所有非唯一值(即:重复/多次出现)


418

我需要检查一个JavaScript数组,看看是否有重复的值。最简单的方法是什么?我只需要查找重复的值是什么-我实际上不需要它们的索引或它们被重复多少次。

我知道我可以遍历数组并检查所有其他值是否匹配,但是似乎应该有一种更简单的方法。

类似的问题:


22
关于这个问题的要求似乎有多年的困惑。我需要知道数组中哪些元素是重复的:“我只需要查找重复的值是什么”。正确答案不应从阵列中删除重复项。那就是我想要的反面:重复项列表,而不是唯一元素列表。
Scott Saunders

Answers:


301

您可以对数组进行排序,然后遍历整个数组,然后查看下一个(或上一个)索引是否与当前索引相同。假设您的排序算法很好,则应小于O(n 2):

const findDuplicates = (arr) => {
  let sorted_arr = arr.slice().sort(); // You can define the comparing function here. 
  // JS by default uses a crappy string compare.
  // (we use slice to clone the array so the
  // original array won't be modified)
  let results = [];
  for (let i = 0; i < sorted_arr.length - 1; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
      results.push(sorted_arr[i]);
    }
  }
  return results;
}

let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7];
console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);

以防万一,如果要作为重复函数返回。这适用于类似情况。

参考: https //stackoverflow.com/a/57532964/8119511


10
“假设您的排序算法很好,则该值应小于O ^ 2”。具体来说,它可以是O(n * log(n))。
ESRogs,2009年

83
此脚本无法与2个以上的重复副本配合使用(例如arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie 2010年

7
@swilliams我不认为这些准则说明不使用i++。相反,他们说不写j = i + +j。恕我直言,两件事不同。我认为i += 1比简单漂亮的方法更让人困惑i++:)
Danilo Bargen 2010年

34
-1这个答案在许多层面上都是错误的。首先var sorted_arr = arr.sort()是无用的:arr.sort()改变原始数组(这本身就是一个问题)。这也会丢弃一个元素。(运行上面的代码。9会发生什么?)cc @dystroy一个更干净的解决方案是results = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException 2013年

24
所有人:问题要求显示重复值,而不是删除它们。请不要编辑/破坏代码以尝试使其执行不想要的操作。警报应显示重复的值。
斯科特·桑德斯

205

如果您想消除重复项,请尝试以下出色的解决方案:

function eliminateDuplicates(arr) {
  var i,
      len = arr.length,
      out = [],
      obj = {};

  for (i = 0; i < len; i++) {
    obj[arr[i]] = 0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}

来源:http//dreaminginjavascript.wordpress.com/2008/08/22/eliminate-duplicates/


18
那是好的代码,但是不幸的是,它并没有满足我的要求。
斯科特·桑德斯

67
上面的代码(这是我的-这是我的博客)使您非常接近。稍作调整,您就可以在那里。首先,您可以查看arr.length和out.length是否相同。如果它们相同,则没有重复的元素。但是您想要更多。如果您想在偶像发生时“捕获”它们,请检查obj [arr [i]] = 0行之后数组的长度是否增加。漂亮,是吗?:-)感谢拉斐尔·蒙塔纳罗(Raphael Montanaro)的好话。
Nosredna

6
@MarcoDemaio:嗯,不,为什么代码不能与空格一起使用?您可以在属性名称中添加任何内容-只是不能使用点语法来访问带空格的内容(也不能使用带有其他可能破坏解析的其他字符的prop)。
Gijs

4
@吉斯:+1你是对的。我不知道 但是当它是对象数组时,它仍然不起作用。
Marco Demaio 2011年

3
此算法还具有返回已排序数组的副作用,这可能不是您想要的。
不对称的

165

这是我对重复线程(!)的回答:

在编写此条目2014时-所有示例均为for循环或jQuery。Javascript为此提供了完美的工具:排序,映射和归约。

查找重复项

var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

var uniq = names
  .map((name) => {
    return {
      count: 1,
      name: name
    }
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)

console.log(duplicates) // [ 'Nancy' ]

更多功能语法:

@ Dmytro-Laptin指出了一些要删除的代码。这是相同代码的更紧凑版本。使用一些ES6技巧和高阶函数:

const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

const count = names =>
  names.reduce((a, b) => ({ ...a,
    [b]: (a[b] || 0) + 1
  }), {}) // don't forget to initialize the accumulator

const duplicates = dict =>
  Object.keys(dict).filter((a) => dict[a] > 1)

console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]


1
这是我一直在寻找的解决方案。如果我想有十二个for循环,那很容易编写。OP中的关键词是“高效”。
乔什(Josh)2016年

@ChristianLandgren,“ dict”变量在哪里声明?也许应该使用“计数”代替?
Dmytro Laptin '16

4
请自己保留您的误导性意见(自大为-1)。我个人讨厌人们混淆“简短”和“高效”,并张贴单行而不质疑表演。短程序和现代JS本质上并不是更好。这个词的典型滥用“高效” 在这里。典型的天真的信念在这里(阅读以下评论)。演示在这里

1
@leaf-请根据您自己的回答提出建议。您编辑的解决方案不可读,它可能是高性能的(可能不是),但即使如此-在我看来,可读性通常比性能更重要。但最重要的是-不要删除别人的代码以无故用你的代码代替。
Christian Landgren

1
不同的答案,是的,不同的意见,我不这么认为。

64

在数组中查找重复值

这应该是在数组中实际查找重复值的最短方法之一。正如OP明确要求的那样,这不会删除重复项,而是会找到它们

var input = [1, 2, 3, 1, 3, 1];

var duplicates = input.reduce(function(acc, el, i, arr) {
  if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);

document.write(duplicates); // = 1,3 (actual array == [1, 3])

这不需要排序或任何第三方框架。它也不需要手动循环。它与indexOf()的每个值(或更清楚地说:严格的比较运算符)支持一起使用。

由于reduce()indexOf(),因此至少需要IE 9。


7
ES6箭头/简单/纯版本:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies

30

您可以添加此函数,也可以对其进行调整并将其添加到Javascript的Array原型中:

Array.prototype.unique = function () {
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
    {
        for(var x = 0, y = r.length; x < y; x++)
        {
            if(r[x]==this[i])
            {
                alert('this is a DUPE!');
                continue o;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);

这是最好的解决方案,但是要小心地将其添加到数组原型中,因为如果循环遍历这些值,将会搞乱IE。
Sampsa Suoninen 2012年

@RoyTinker perl也支持它们,但我不知道javascript是否支持
Luke H

1
不执行OP要求的操作,返回重复项。
RWC

27

更新:以下使用优化的组合策略。它优化了原始查询,以受益于哈希O(1)查找时间(unique在原始数组上运行的是O(n))。通过在迭代过程中使用唯一ID标记对象来优化对象查找,因此,标识重复的对象也是每个项目O(1)和整个列表O(n)。唯一的例外是已冻结的项目,但这些项目很少见,并且使用array和indexOf提供了回退。

var unique = function(){
  var hasOwn = {}.hasOwnProperty,
      toString = {}.toString,
      uids = {};

  function uid(){
    var key = Math.random().toString(36).slice(2);
    return key in uids ? uid() : uids[key] = key;
  }

  function unique(array){
    var strings = {}, numbers = {}, others = {},
        tagged = [], failed = [],
        count = 0, i = array.length,
        item, type;

    var id = uid();

    while (i--) {
      item = array[i];
      type = typeof item;
      if (item == null || type !== 'object' && type !== 'function') {
        // primitive
        switch (type) {
          case 'string': strings[item] = true; break;
          case 'number': numbers[item] = true; break;
          default: others[item] = item; break;
        }
      } else {
        // object
        if (!hasOwn.call(item, id)) {
          try {
            item[id] = true;
            tagged[count++] = item;
          } catch (e){
            if (failed.indexOf(item) === -1)
              failed[failed.length] = item;
          }
        }
      }
    }

    // remove the tags
    while (count--)
      delete tagged[count][id];

    tagged = tagged.concat(failed);
    count = tagged.length;

    // append primitives to results
    for (i in strings)
      if (hasOwn.call(strings, i))
        tagged[count++] = i;

    for (i in numbers)
      if (hasOwn.call(numbers, i))
        tagged[count++] = +i;

    for (i in others)
      if (hasOwn.call(others, i))
        tagged[count++] = others[i];

    return tagged;
  }

  return unique;
}();

如果您有可用的ES6集合,那么会有一个更简单且明显更快的版本。(适用于IE9 +和其他浏览器的Shim,位于:https : //github.com/Benvie/ES6-Harmony-Collections-Shim

function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}

真?为什么要回答两年前已经解决的问题?
Rene Pot

3
我在回答另一个问题,显然是不小心点击了链接到该问题的某人,称其为重复项,最终克隆了我的答案,使自己陷入混乱。我经常编辑我的东西。


16
我认为使用不同的解决方案很好。主题既旧又解决也没关系,因为仍然可以提出不同的方法来实现。这是计算机科学中的一个典型问题。
EmilVikström,

你可能想提一提,这依赖于未在IE <9实现ES5 Array方法
蒂姆下

24

更新:简短的一线以获得重复:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]

要获得没有重复的数组,只需将条件求反即可:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]

我只是filter()在下面的旧答案中没有考虑过;)


当您只需要检查是否存在此问题所要求的重复项时,可以使用以下every()方法:

[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true

[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false

请注意,该every()功能不适用于IE 8及更低版本。


1
不执行OP要求的操作,返回重复项。
RWC

是的,我更新了答案以解决此问题。
劳伦·帕伊特

御解!致谢
杰里米·

21
var a = ["a","a","b","c","c"];

a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})

这似乎可行,但是您可能应该包括一些描述其工作原理的文本。
DIMM收割机

1
如果出现两次以上的重复值,则无法使用。
vasa 2015年

1
这是优雅而简单的。我喜欢它。对于那些想弄清楚它们是如何工作的人,我创建了一个要点,展示了如何显示重复项并消除重复项。看到这里:gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@TheDIMMReaper 'a'阵列中的第二个,内部过滤器函数index == 1,而self.indexOf('a') == 0
Sergiy Ostrovsky

19

这应该为您提供所需的东西,只是重复项。

function find_duplicates(arr) {
  var len=arr.length,
      out=[],
      counts={};

  for (var i=0;i<len;i++) {
    var item = arr[i];
    counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
    if (counts[item] === 2) {
      out.push(item);
    }
  }

  return out;
}

find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.


9

ES2015

//          🚩🚩   🚩                 🚩 
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    unique;

// Combine all the arrays to a single one
unique = arr.concat(arr2, arr3)

// create a new (dirty) Array with only the unique items
unique = unique.map((item,i) => unique.includes(item, i+1) ? item : '' )

// Cleanup - remove duplicate & empty items items 
unique = [...new Set(unique)].filter(n => n)

console.log(unique)


从3个数组(或更多数组)中查找唯一值:

Array.prototype.unique = function () {
    var arr = this.sort(), i; // input must be sorted for this to work
    for( i=arr.length; i--; )
      arr[i] === arr[i-1] && arr.splice(i,1); // remove duplicate item

    return arr;
}

var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,9],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    // merge arrays & call custom Array Prototype - "unique"
    unique = arr.concat(arr2, arr3).unique();

console.log(unique);  // [22, 50, 12, 511, 2, 1, 9, 5, 8, 7, 3, 6, 4]

只是旧浏览器的数组indexOf的polyfill:

if (!Array.prototype.indexOf){
   Array.prototype.indexOf = function(elt /*, from*/){
     var len = this.length >>> 0;

     var from = Number(arguments[1]) || 0;
     from = (from < 0) ? Math.ceil(from) : Math.floor(from);
     if (from < 0)
        from += len;

     for (; from < len; from++){
        if (from in this && this[from] === elt)
           return from;
     }
     return -1;
  };
}

jQuery解决方案使用“ inArray”:

if( $.inArray(this[i], arr) == -1 )

而不是添加 Array.prototype.indexOf


+1,因为使用Array.indexOf绝对可以使代码更具可读性,但不幸的是,它似乎比使用简单的嵌套循环慢。即使在像FF这样天真的实现Array.indexOf的浏览器上。请看看我在这里所做的这些测试:jsperf.com/array-unique2,让我知道您的想法。
Marco Demaio 2011年

@shekhardesigner-更新答案。“ r”是您要搜索的数组
vsync

@vsync我必须初始化,var r = [];以使您的代码正常工作。并像魅力一样工作。
Shekhar K. Sharma 2014年

@shekhardesigner -我为混合抱歉,该阵列原型解决方案,你并不需要一个r变量
VSYNC

2
不执行OP要求的操作,返回重复项。
RWC

8

这是我的简单和一线解决方案。

它首先搜索非唯一元素,然后使用Set使找到的数组唯一。

因此,最后有重复的数组。

var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];

console.log([...new Set(
  array.filter((value, index, self) => self.indexOf(value) !== index))]
);


7

这是我的建议(ES6):

let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]

// b is now [1, 2, 4]

1
这将报告的单次出现undefined是重复的。
Dem Pilafian

1
@DemPilafian谢谢您,更新
lukaszkups

6
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});

或添加到Array的原型链时

//copy and paste: without error handling
Array.prototype.unique = 
   function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}

看到这里:https : //gist.github.com/1305056


1
筛选器函数应返回true或false,而不是元素本身。过滤包含0的数组将不会返回它们。
mflodin

另外,我假设的用意i&&是避免超出数组的范围,但这也意味着排序后的数组中的第一个元素将不包括在内。在您的示例1中,结果数组中没有任何内容。即return i&&v!==o[i-1]?v:0;应该是return v!==o[i-1];
mflodin 2012年

6

使用ES6对象分解和减少的快速而优雅的方式

它以O(n)运行(在数组上进行1次迭代),并且不会重复出现超过2次的值

const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']
const {
  dup
} = arr.reduce(
  (acc, curr) => {
    acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
    if (acc.items[curr] === 2) acc.dup.push(curr)
    return acc
  }, {
    items: {},
    dup: []
  },
)

console.log(dup)
// ['hi', 'bye']


5

这是我能想到的最简单的解决方案:

    const arr = [-1, 2, 2, 2, 0, 0, 0, 500, -1, 'a', 'a', 'a']

    const filtered = arr.filter((el, index) => arr.indexOf(el) !== index)
    // => filtered = [ 2, 2, 0, 0, -1, 'a', 'a' ]

    const duplicates = [...new Set(filtered)]

    console.log(duplicates)
    // => [ 2, 0, -1, 'a' ]

而已。

注意:

  1. 它适用于任何数字,包括0,字符串和负数,例如-1- 相关问题: 获取JavaScript数组中的所有唯一值(删除重复项)

  2. arr保留原始数组(filter返回新数组而不是修改原始数组)

  3. filtered数组包含所有重复项。它可以包含1个以上相同的值(例如,这里的过滤数组是[ 2, 2, 0, 0, -1, 'a', 'a' ]

  4. 如果你想获得是重复的值(你不希望有相同值的多个副本),可以使用[...new Set(filtered)](ES6都有一个对象可存储唯一的值)

希望这可以帮助。


5

最短的香草JS

[1,1,2,2,2,3].filter((v,i,a) => a.indexOf(v) !== i) // [1, 2, 2]

4

这是一个非常简便的方法:

var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}

最佳答案。如果用户想要重复元素数组,为此,我更新了@brandon代码var i =代码.length;。varplicate = []; while(i--){if(codes.indexOf(codes [i])!= i){if(duplicate.indexOf(codes [i])=== -1){plicate.push(arr [i]) ; } code.splice(i,1); }
Himanshu Shekhar

4

使用ES6(或使用Babel或Typescipt),您可以简单地执行以下操作:

var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);

https://es6console.com/j58euhbt/


我独立地使用了相同的语法,当我发现这一语法时,我正打算将其添加为解决方案。它可能不是最经济的,但是很简单。
nize '18

4

使用ES6语法的简单代码(返回重复的排序数组):

let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};

如何使用:

duplicates([1,2,3,10,10,2,3,3,10]);

1
.filter()会简单得多
tocqueville

4

一支班轮

var arr = [9,1,2,4,3,4,9]
console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates


是什么indx!在第一个例子吗?
saylestyler

1
@saylestyler呵呵,这意味着indx !== ...-严格的不平等。
Daria

仅添加对象数组result.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix

4

这个答案可能也有帮助,它利用js reduce 运算符/方法从数组中删除重复项

const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);

console.log(result);


3
我们现在new Set([1, 2, 2, 3, 3, 3, 3])可以删除重复项
kimbaudi

3

下面的函数(已经提到了excludeDuplicates函数的变体)似乎可以解决问题,为输入[“ test”,“ test2”,“ test2”,1、1、1、2返回test2,1,7,5 ,3、4、5、6、7、7、10、22、43、1、5、8]

请注意,JavaScript比大多数其他语言中的问题更奇怪,因为JavaScript数组几乎可以容纳任何东西。请注意,使用排序的解决方案可能需要提供适当的排序功能-我还没有尝试过这种方法。

此特定实现适用于(至少)字符串和数字。

function findDuplicates(arr) {
    var i,
        len=arr.length,
        out=[],
        obj={};

    for (i=0;i<len;i++) {
        if (obj[arr[i]] != null) {
            if (!obj[arr[i]]) {
                out.push(arr[i]);
                obj[arr[i]] = 1;
            }
        } else {
            obj[arr[i]] = 0;            
        }
    }
    return out;
}

3

仅适用于ES5(即,它需要针对IE8及更低版本的filter()polyfill):

var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];

arrayToFilter.
    sort().
    filter( function(me,i,arr){
       return (i===0) || ( me !== arr[i-1] );
    });

我喜欢这个简单的解决方案。但是,如果需要重复项,则需要先找到那些重复项,然后使重复项列表唯一。[0,4,5,5,5,2,1,3,1,1,2,1,3] .sort()。filter(function(me,i,arr){return(i!== 0 )&&(me == arr [i-1]);})。filter(function(me,i,arr){return(i === 0)||(me!== arr [i-1]) ;});
格雷格

3

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

function returnDuplicates(arr) {
  return arr.reduce(function(dupes, val, i) {
    if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
      dupes.push(val);
    }
    return dupes;
  }, []);
}

alert(returnDuplicates(arr));

此函数避免了排序步骤,并使用reduce()方法将重复项推入新数组(如果尚不存在)。


3

这可能是从阵列中永久删除重复项的最快方法之一, 比此处的大多数功能快10倍。在Safari中快78倍。

function toUnique(a,b,c){//array,placeholder,placeholder
 b=a.length;
 while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
toUnique(array);
console.log(array);
  1. 测试:http//jsperf.com/wgu
  2. 演示:http : //jsfiddle.net/46S7g/
  3. 更多:https//stackoverflow.com/a/25082874/2450730

如果您看不懂上面的代码,请阅读一本javascript书籍,或以下有关较短代码的说明。https://stackoverflow.com/a/21353032/2450730

编辑 如评论中所述,此函数确实返回具有唯一性的数组,但是问题要求查找重复项。在这种情况下,对该函数的简单修改就可以将重复项推入数组,然后使用先前的功能toUnique删除重复项的重复项。

function theDuplicates(a,b,c,d){//array,placeholder,placeholder
 b=a.length,d=[];
 while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
}
var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

toUnique(theDuplicates(array));

7
“如果您看不懂上面的代码,请阅读一本javascript书。”这个答案中有太多代码。将变量命名为a,b,c之类的东西会使代码难以阅读。放弃大括号会使情况更糟。
威廉姆森河2015年

我大部分的答案都是基于性能和空间节省(其他解决方案已经发布)...如果您不喜欢它,请投票...否则学习javascript,阅读js书籍或使用jquery ...他们如果您搜索一个简单的解决方案,还有更多答案。如果您真的想学习一些东西,我很乐于解释每个字母的代码字母。由于我在您的评论中看不到一个真正的问题,我想您只是在寻找动机来拒绝我的答案....继续...我对此没有任何问题。问一个真正的问题或告诉我一些与我的代码不兼容的内容。
cocco

9
您的代码在技术上没有错。也就是说,命名变量a,b,c,d等并链接while循环会使代码难以阅读。因此,该代码无法教授任何内容。
威廉姆森河

3

使用“包含”测试元素是否已经存在。

var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];

for(var i = 0; i < arr.length; i++){
  if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))
    duplicates.push(arr[i])
  else
    darr.push(arr[i]);
}

console.log(duplicates);
<h3>Array with duplicates</h3>
<p>[1, 1, 4, 5, 5]</p>
<h3>Array with distinct elements</h3>
<p>[1, 4, 5]</p>
<h3>duplicate values are</h3>
<p>[1, 5]</p>


该代码确实返回了不同的元素,但没有得到给定的结果。请提供完整的正确代码。
RWC

3

ES6提供了Set数据结构,该结构基本上是一个不接受重复项的数组。使用Set数据结构,有一种非常简单的方法来查找数组中的重复项(仅使用一个循环)。

这是我的代码

function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
  for (let i = 0; i< arr.length; i++) {
     var size = set.size;
     set.add(arr[i]);
     if (set.size === size) {
         duplicates.add(arr[i]);
     }
  }
 return duplicates;
}

3

我刚刚想出一种使用数组过滤器实现此目的的简单方法

    var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];
    
    // Filter 1: to find all duplicates elements
    var duplicates = list.filter(function(value,index,self) {
       return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
    });
    
    console.log(duplicates);


3

遵循逻辑将变得更加轻松快捷

// @Param:data:Array that is the source 
// @Return : Array that have the duplicate entries
findDuplicates(data: Array<any>): Array<any> {
        return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
      }

优点 :

  1. 单行:-P
  2. 所有内置的数据结构有助于提高效率
  3. 快点

逻辑说明:

  1. 转换为设置以删除所有重复项
  2. 遍历设置值
  3. 对于源数组中的每个设置值,检查条件“值第一个索引不等于最后一个索引” ==>然后推断为重复,否则为“唯一”

注意: map()和filter()方法高效且快速。


1
测试这个...非常快。并说得通..希望我考虑一下
Michael Rhema
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.