配列内のすべての一意でない値(つまり、重複/複数)を取得します


418

JavaScript配列をチェックして、重複する値がないかどうかを確認する必要があります。これを行う最も簡単な方法は何ですか?重複する値が何であるかを見つける必要があるだけです-実際にはそれらのインデックスや重複する回数は必要ありません。

配列をループして他のすべての値をチェックして一致を確認できることはわかっていますが、もっと簡単な方法があるはずです。

同様の質問:


22
この質問が何を尋ねているかについて、長年の混乱があるようです。配列のどの要素が複製されているかを知る必要がありました:「複製された値が何であるかを見つける必要があるだけです」。正しい答えは、配列から重複を削除してはなりません。それは私が欲しかったものの逆です:重複のリストであり、ユニークな要素のリストではありません。
スコットサンダース

回答:


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

7
@swilliams私はそれらのガイドラインがを使用しないことについて何も述べていないと思いますi++。代わりに、彼らは書きませんと言いますj = i + +j。2つの異なるもの私見。私i += 1はシンプルで美しいよりも混乱していると思いますi++:)
Danilo Bargen

34
-1この答えは多くのレベルで間違っています。まず、var sorted_arr = arr.sort()役に立たない:arr.sort()元の配列を変更します(それ自体が問題です)。これにより、要素も破棄されます。(上記のコードを実行します。9はどうなりますか?)cc @dystroyよりクリーンな解決策はresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException

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/elimination-duplicates/


18
これは良いコードですが、残念ながら私が求めていることはできません。
スコットサンダース

67
上記のコード(これは私のブログです)を使用すると、かなり親密になります。小さな微調整とそこにいます。まず、arr.lengthとout.lengthが同じかどうかを確認できます。それらが同じ場合、重複する要素はありません。しかし、もう少し欲しい。デュプが発生したときにデュプを「キャッチ」するには、obj [arr [i]] = 0行の後で配列の長さが増加するかどうかを確認します。気の利いた、え?:-)素敵な言葉をありがとう、ラファエル・モンタナロ。
Nosredna 2009年

6
@MarcoDemaio:ええと、いや、なぜコードがスペースで機能しないのですか?プロパティ名には好きなものを置くことができます-ドット構文を使用してスペースを含むものにアクセスすることはできません(解析を壊す他のさまざまな文字を含む小道具も)。
Gijs

4
@Gijs:+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
これは私が探していた種類のソリューションです。12個のforループが必要な場合は、これを書くのは非常に簡単です。OPのキーワードは「効率的」でした。
Josh

@ChristianLandgren、「dict」変数はどこで宣言されていますか?代わりに「カウント」を使用する必要がありますか?
Dmytro Laptin

4
誤解を招くような意見は自分で保管してください(傲慢であることを示す-1)。私は個人的に「短い」と「効率的な」を混同し、パフォーマンスを疑うことなくワンライナーを投稿する人々にうんざりしています。短いプログラムと最新のJSは、本質的には良くありません。ここでの「効率的な」という単語の典型的な誤用。ここでの典型的な素朴な信念(以下のコメントを読んでください)。デモはこちら

1
@leaf-自分の答えに対する提案を保管してください。あなたが編集したソリューションは可読ではありません。パフォーマンスが良い(おそらく不可)かもしれませんが、そうであっても、私の意見では、可読性がパフォーマンスよりも重要であることがよくあります。しかし、最も重要なことは、他の誰かのコードを削除して、理由なく自分のものに置き換えないことです。
Christian Landgren

1
別の答え、そう、別の意見、私はそうは思いません。

64

配列内の重複する値を見つける

これは、配列内の重複する値を実際に見つける最も短い方法の1つです。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が台無しになるためです。
サンプサスオニネン

@RoyTinker perlもそれらをサポートしていますが、javascriptがサポートしているとは思いもしませんでした
Luke H

1
OPが要求したことを行わず、重複を返します。
RWC、2017

27

更新:以下は、最適化された組み合わせ戦略を使用しています。プリミティブルックアップを最適化して、ハッシュO(1)ルックアップ時間のメリットを享受します(uniqueプリミティブの配列で実行するとO(n)になります)。オブジェクトのルックアップは、反復処理中にオブジェクトに一意のIDのタグを付けることで最適化されるため、重複オブジェクトの識別もアイテムごとにO(1)、リスト全体に対してO(n)になります。唯一の例外は凍結されたアイテムですが、それらはまれであり、配列と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 +およびその他のブラウザーのシム: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;
    }
  });
}

本当に?なぜ2年以上前に解決された質問に答えるのですか?
ルネ・ポット

3
私は別の質問に答えていて、どうやらこの質問にリンクしている誰かを誤ってクリックして、それを複製と呼び、私の答えを複製して自分自身を混乱させました。私は自分の作品を頻繁に編集しています。


16
私はそれがさまざまなソリューションでいいと思います。トピックが古く、解決されていることは問題ではありません。これを行うにはさまざまな方法が考えられるからです。これはコンピュータサイエンスの典型的な問題です。
EmilVikström

これは、IE <9で実装されていないES5配列メソッドに依存していることを言及する必要があるかもしれません
Tim Down

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 2017

確かに、私はそれを修正するために私の答えを更新しました。
Laurent Payot

ロイヤルソリューション!thnaks
ジェレミーピエドノエル

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

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

これは機能しているようですが、機能する方法を説明するテキストを含める必要があります。
DIMMリーパー

1
重複する値が2つ以上ある場合は機能しません。
vasa

1
これはエレガントでシンプルです。大好きです。それらがどのように機能するかを理解したい人のために、重複を表示して重複を排除する方法を示す要点を作成しました。こちらをご覧ください:gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh

@TheDIMMReaper for the second 'a'in array、inside filter function the 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のポリフィル:

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;
  };
}

「inArray」を使用したjQueryソリューション:

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

追加する代わりに Array.prototype.indexOf


+1は、Array.indexOfを使用するコードの方が間違いなく読みやすいためですが、残念ながら、単純なネストされたループを使用するよりも遅くなります。ナイーブにFFのようにArray.indexOfを実装するブラウザーでもです。Plz、私がここで行ったこれらのテストを見てください:jsperf.com/array-unique2そしてあなたの考えを私に知らせてください。
Marco Demaio、2011年

@shekhardesigner-更新された回答。「r」は検索する配列です
vsync

@vsync var r = [];コードを機能させるために、初期化する必要がありました。そして魅力のように働いた。
Shekhar K. Sharma 14

@shekhardesigner-配列のプロトタイプソリューションではr変数は必要ありません
vsync

2
OPが要求したことを行わず、重複を返します。
RWC

8

これが私の簡単な1行のソリューションです。

最初に一意の要素ではなく、次に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
これは、の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;});

または配列のprototyp.chainに追加されたとき

//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 2012年

また、i&&配列の境界から外れないようにするためだと思いますが、これは、ソートされた配列の最初の要素が含まれないことも意味します。あなたの例では1、結果の配列にはありません。つまりは、return i&&v!==o[i-1]?v:0;あるべきreturn v!==o[i-1];
mflodin

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 duplicate = []; while(i--){if(codes .indexOf(codes [i])!= i){if(duplicate.indexOf(codes [i])=== -1){duplicate.push(arr [i]) ; } codes.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

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 Hehe、これは意味します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()ポリフィルが必要です):

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倍高速に配列から重複を永久に削除する最も速い方法の1つです。&サファリでは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などの名前を付けると、コードが読みにくくなります。中かっこを控えるとさらに悪化します。
ウィリアムソン川

私の答えのほとんどはパフォーマンスとスペースの節約に基づいています(他のソリューションはすでに投稿されています)...反対票を投じたくない場合は... JavaScriptを学び、jsブックを読む...またはjqueryを使用してください...彼らは簡単な解決策を検索すると、さらに多くの答えが得られます。あなたが本当に何かを学びたいのなら、私は文字ごとにコード文字を説明させていただきます。コメントに本当の質問が見当たらないので、私の回答に反対票を投じる動機を探しているだけだと思います...続けてください...問題ありません。本当の質問をするか、私のコードで動作しない何かを教えてください。
cocco

9
コードに技術的に問題はありません。つまり、変数a、b、c、dなどに名前を付け、whileループをチェーンすると、コードが読みにくくなります。したがって、コードは何も教えることができません。
ウィリアムソン川

3

「includes」を使用して、要素がすでに存在するかどうかをテストします。

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、2017年

3

ES6は、基本的に重複を受け入れない配列であるSetデータ構造を提供します。Setデータ構造を使用すると、配列内の重複を見つける非常に簡単な方法があります(1つのループのみを使用)。

これが私のコードです

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
これをテストした...非常に高速。そしてそれは理にかなっている..私がそれについて考えていたらいいのに
マイケル・レーマ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.