Récupère toutes les valeurs non uniques (ex: doublon / plusieurs occurrences) dans un tableau

418

J'ai besoin de vérifier un tableau JavaScript pour voir s'il y a des valeurs en double. Quelle est la façon la plus simple de procéder? J'ai juste besoin de trouver quelles sont les valeurs dupliquées - je n'ai pas réellement besoin de leurs index ou combien de fois elles sont dupliquées.

Je sais que je peux parcourir le tableau et vérifier toutes les autres valeurs pour une correspondance, mais il semble qu'il devrait y avoir un moyen plus simple.

Question similaire:

Scott Saunders
la source
22
Il semble y avoir des années de confusion sur ce que cette question demande. J'avais besoin de savoir quels éléments du tableau étaient dupliqués: "J'ai juste besoin de trouver quelles sont les valeurs dupliquées". La bonne réponse ne doit PAS supprimer les doublons du tableau. C'est l'inverse de ce que je voulais: une liste des doublons, pas une liste d'éléments uniques.
Scott Saunders

Réponses:

302

Vous pouvez trier le tableau, puis le parcourir et voir si l'index suivant (ou précédent) est le même que l'actuel. En supposant que votre algorithme de tri est bon, il devrait être inférieur à 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)}`);

Dans le cas, si vous devez retourner en tant que fonction pour les doublons. C'est pour un type de cas similaire.

Référence: https://stackoverflow.com/a/57532964/8119511

swilliams
la source
10
Msgstr "En supposant que votre algorithme de tri soit bon, il devrait être inférieur à O ^ 2". Plus précisément, il peut s'agir de O (n * log (n)).
ESRogs
83
Ce script ne fonctionne pas si bien avec plus de 2 doublons (par exemplearr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7];
Mottie
7
@swilliams Je ne pense pas que ces directives disent rien de ne pas utiliser i++. Au lieu de cela, ils disent de ne pas écrire j = i + +j. Deux choses différentes à mon humble avis. Je pense que i += 1c'est plus déroutant que le simple et le beau i++:)
Danilo Bargen
34
-1 Cette réponse est fausse à plusieurs niveaux. Tout d'abord var sorted_arr = arr.sort()est inutile: arr.sort()mute le tableau d'origine (ce qui est un problème en soi). Cela supprime également un élément. (Exécutez le code ci-dessus. Qu'arrive-t-il à 9?) Cc @dystroy Une solution plus propre seraitresults = arr.filter(function(elem, pos) { return arr.indexOf(elem) == pos; })
NullUserException
24
Tout le monde: la question demande d'afficher les valeurs en double, pas de les supprimer. Veuillez ne pas modifier / casser le code pour essayer de le faire faire quelque chose qu'il n'essaie pas de faire. L'alerte doit montrer les valeurs qui sont dupliquées.
Scott Saunders
205

Si vous souhaitez éliminer les doublons, essayez cette excellente solution:

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

Source: http://dreaminginjavascript.wordpress.com/2008/08/22/iminating-duplicates/

rapfaria
la source
18
C'est du bon code, mais malheureusement il ne fait pas ce que je demande.
Scott Saunders
67
Le code ci-dessus (qui est le mien - c'est mon blog) vous rapproche assez. Un petit tweak et vous y êtes. Tout d'abord, vous pouvez voir si la longueur d'arrivée et la longueur de sortie sont identiques. S'ils sont identiques, il n'y a pas d'éléments dupliqués. Mais vous en voulez un peu plus. Si vous voulez "attraper" les dupes à mesure qu'elles se produisent, vérifiez si la longueur du tableau augmente après la ligne obj [arr [i]] = 0. Nifty, hein? :-) Merci pour ces belles paroles, Raphael Montanaro.
Nosredna
6
@MarcoDemaio: Euh, non, pourquoi le code ne fonctionnerait-il pas avec des espaces? Vous pouvez mettre ce que vous voulez dans un nom de propriété - vous ne pouvez pas utiliser la syntaxe à points pour accéder à ceux avec des espaces (ni aux accessoires avec divers autres caractères qui briseraient l'analyse).
Gijs
4
@Gijs: +1 vous avez raison. Je ne le savais pas. Mais cela ne fonctionne toujours pas lorsqu'il s'agit d'un tableau d'objets.
Marco Demaio
3
Cet algorithme a également pour effet secondaire de renvoyer un tableau trié, qui pourrait ne pas être ce que vous voulez.
asymétrique
166

Voici ma réponse du fil en double (!):

Lors de l'écriture de cette entrée 2014 - tous les exemples étaient des boucles for ou jQuery. Javascript a les outils parfaits pour cela: trier, mapper et réduire.

Rechercher des éléments en double

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' ]

Syntaxe plus fonctionnelle:

@ Dmytro-Laptin a souligné que certains codes étaient supprimés. Il s'agit d'une version plus compacte du même code. Utilisation de quelques astuces ES6 et de fonctions d'ordre supérieur:

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' ]

Christian Landgren
la source
1
C'est le genre de solution que je cherchais. Si je voulais avoir une douzaine de boucles for, ce serait assez facile à écrire. Le mot clé du PO était "efficace".
Josh
@ChristianLandgren, où la variable 'dict' est-elle déclarée? peut-être que "count" devrait être utilisé à la place?
Dmytro Laptin
4
Veuillez garder votre opinion trompeuse pour vous-même (-1 pour être arrogant). Je suis personnellement fatigué des gens qui confondent "court" et "efficace", et qui affichent des doublures sans remettre en question les performances. Les programmes courts et les JS modernes ne sont PAS meilleurs par nature. Mauvais usage typique du mot «efficace» ici . Croyance naïve typique ici (lire les commentaires suivants). Démo ici .
le
1
@leaf - veuillez conserver vos suggestions dans vos propres réponses. La solution que vous avez éditée n'est pas lisible, elle peut être performante (probablement pas) mais même ainsi - la lisibilité est souvent plus importante que les performances à mon avis. Mais le plus important - ne supprimez pas le code de quelqu'un d'autre pour le remplacer par le vôtre sans raison.
Christian Landgren
1
Différentes réponses, oui, différentes opinions, je ne pense pas.
le
64

Rechercher des valeurs en double dans un tableau

Cela devrait être l'un des moyens les plus courts de trouver des valeurs en double dans un tableau. Comme spécifiquement demandé par le PO, cela ne supprime pas les doublons mais les trouve .

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])

Cela n'a pas besoin de tri ni de cadre tiers. Il n'a pas non plus besoin de boucles manuelles. Il fonctionne avec toutes les valeurs prises en charge par indexOf () (ou pour être plus clair: l' opérateur de comparaison strict ).

En raison de Reduce () et indexOf (), il nécessite au moins IE 9.

grippe
la source
7
Flèche ES6 / version simple / pure:const dupes = items.reduce((acc, v, i, arr) => arr.indexOf(v) !== i && acc.indexOf(v) === -1 ? acc.concat(v) : acc, [])
ZephDavies
30

Vous pouvez ajouter cette fonction, ou la modifier et l'ajouter au prototype de tableau de Javascript:

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);
karim79
la source
C'est la meilleure solution, mais attention à l'ajouter au prototype de tableau, car cela gâcherait IE si vous parcourez les valeurs.
Sampsa Suoninen du
@RoyTinker perl les prend également en charge, mais je n'avais aucune idée que javascript l'a fait
Luke H
1
Ne fait pas ce que l'OP a demandé, retourne les doublons.
RWC
27

MISE À JOUR: Ce qui suit utilise une stratégie combinée optimisée. Il optimise les recherches de primitives pour bénéficier du temps de recherche de hachage O (1) (l'exécution uniquesur un tableau de primitives est O (n)). Les recherches d'objets sont optimisées en étiquetant les objets avec un identifiant unique lors de l'itération, de sorte que l'identification des objets en double est également O (1) par élément et O (n) pour toute la liste. La seule exception concerne les éléments gelés, mais ceux-ci sont rares et une solution de secours est fournie à l'aide d'un tableau et d'un 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;
}();

Si vous avez des collections ES6 disponibles, il existe une version beaucoup plus simple et beaucoup plus rapide. (shim pour IE9 + et autres navigateurs ici: 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;
    }
  });
}

la source
vraiment? pourquoi répondre à une question qui a été résolue il y a plus de 2 ans?
Rene Pot
3
Je répondais à une autre question et, apparemment, j'ai accidentellement cliqué sur quelqu'un reliant à celle-ci, l'appelant un duplicata, et j'ai fini par cloner ma réponse et confondre l'enfer de moi-même. J'édite beaucoup mes trucs.
16
Je pense que c'est bien avec différentes solutions. Peu importe que le sujet soit ancien et résolu, car il est toujours possible de trouver différentes façons de le faire. C'est un problème typique en informatique.
Emil Vikström
Vous voudrez peut-être mentionner que cela repose sur des méthodes de tableau ES5 qui ne sont pas implémentées dans IE <9.
Tim Down
24

MISE À JOUR: Short one-liner pour obtenir les doublons:

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

Pour obtenir le tableau sans doublons, inversez simplement la condition:

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

Je n'y pensais tout simplement pas filter()dans mon ancienne réponse ci-dessous;)


Lorsque tout ce dont vous avez besoin est de vérifier qu'il n'y a pas de doublons comme demandé dans cette question, vous pouvez utiliser la every()méthode:

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

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

Notez que every()cela ne fonctionne pas pour IE 8 et les versions antérieures.

Laurent Payot
la source
1
Ne fait pas ce que l'OP a demandé, retourne les doublons.
RWC
Certes, j'ai mis à jour ma réponse pour résoudre ce problème.
Laurent Payot
Solution royale! thnaks
Jeremy Piednoel
21
var a = ["a","a","b","c","c"];

a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})
Angel David Calderaro Pacciott
la source
Cela semble fonctionner, mais vous devriez probablement inclure du texte décrivant comment cela fonctionne.
Le DIMM Reaper
1
Ne fonctionnera pas s'il y a plus de 2 occurrences d'une valeur en double.
vasa
1
C'est élégant et simple. J'aime cela. Pour ceux qui veulent comprendre comment ils fonctionnent, j'ai créé un résumé montrant comment afficher les doublons et éliminer les doublons. Voir ici: gist.github.com/jbcoder/f1c616a32ee4d642691792eebdc4257b
Josh
@TheDIMMReaper pour le second 'a'dans le tableau, la fonction de filtre à l'intérieur du index == 1, alors queself.indexOf('a') == 0
Sergiy Ostrovsky
19

Cela devrait vous procurer ce que vous voulez, juste les doublons.

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.
Daniel Beardsley
la source
13

en utilisant underscore.js

function hasDuplicate(arr){
    return (arr.length != _.uniq(arr).length);
}
Marco Allori
la source
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)


Trouvez des valeurs uniques à partir de 3 tableaux (ou plus):

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]

Juste un polyfill pour array indexOf pour les anciens navigateurs:

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

Solution jQuery utilisant "inArray":

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

au lieu d'ajouter le Array.prototype.indexOf

vsync
la source
+1 parce que le code est certainement plus lisible en utilisant Array.indexOf, mais malheureusement il semble plus lent que d'utiliser une simple boucle imbriquée. Même sur les navigateurs qui implémentent Array.indexOf comme FF. Plz, jetez un œil à ces tests que j'ai faits ici: jsperf.com/array-unique2 et faites-moi part de vos réflexions.
Marco Demaio
@shekhardesigner - réponse mise à jour. "r" est le tableau dans
lequel
@vsync J'ai dû initialiser, var r = [];pour faire fonctionner votre code. Et a travaillé comme un charme.
Shekhar K. Sharma
@shekhardesigner - Je suis désolé pour le mélange, pour la solution Array Prototype, vous n'avez pas besoin d'une rvariable
vsync
2
Ne fait pas ce que l'OP a demandé, retourne les doublons.
RWC
8

Voici la mienne simple et une solution en ligne.

Il recherche d'abord les éléments non uniques, puis rend le tableau trouvé unique avec l'utilisation de Set.

Nous avons donc un tableau de doublons à la fin.

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))]
);

Oleg Abrazhaev
la source
7

Voici ma proposition (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]
lukaszkups
la source
1
Cela signalera qu'une seule occurrence de undefinedest un doublon.
Dem Pilafian
1
@DemPilafian merci, mis à jour
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;});

ou lorsqu'il est ajouté à la chaîne prototyp de 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;});}

Voir ici: https://gist.github.com/1305056

Lorenz Lo Sauer
la source
1
La fonction de filtre doit renvoyer true ou false, pas l'élément lui-même. Le filtrage d'un tableau contenant des 0 ne les aurait pas renvoyés.
mflodin
En outre, je suppose que i&&c'est pour éviter de sortir des limites du tableau, mais cela signifie également que le premier élément du tableau trié ne sera pas inclus. Dans votre exemple, il n'y 1en a pas dans le tableau résultant. À savoir return i&&v!==o[i-1]?v:0;devrait êtrereturn v!==o[i-1];
mflodin
6

Manière rapide et élégante utilisant la déstructuration d'objet es6 et réduisez

Il s'exécute en O (n) (1 itération sur le tableau) et ne répète pas les valeurs qui apparaissent plus de 2 fois

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']

Lucas Janon
la source
5

Voici la solution la plus simple à laquelle j'ai pu penser:

    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' ]

C'est ça.

Remarque:

  1. Il fonctionne avec tous les nombres, y compris les 0chaînes et les nombres négatifs, par exemple -1- Question connexe: Obtenez toutes les valeurs uniques dans un tableau JavaScript (supprimez les doublons)

  2. Le tableau d'origine arrest conservé ( filterrenvoie le nouveau tableau au lieu de modifier l'original)

  3. Le filteredtableau contient tous les doublons; il peut également contenir plus d'une même valeur (par exemple, notre tableau filtré est ici [ 2, 2, 0, 0, -1, 'a', 'a' ])

  4. Si vous souhaitez obtenir uniquement des valeurs dupliquées (vous ne voulez pas avoir plusieurs doublons avec la même valeur), vous pouvez utiliser [...new Set(filtered)](ES6 a un ensemble d' objets qui ne peut stocker que des valeurs uniques)

J'espère que cela t'aides.

Nikola Jovanovic
la source
5

Vanille JS la plus courte :

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

Voici un moyen très léger et simple:

var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}
Brandon Ferrara
la source
Meilleure réponse. Et si l'utilisateur veut un tableau d'éléments en double, pour cela j'ai mis à jour le code @brandon var i = codes .length; 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

Avec ES6 (ou en utilisant Babel ou Typescipt), vous pouvez simplement faire:

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

https://es6console.com/j58euhbt/

tocqueville
la source
Je suis arrivé à la même syntaxe, indépendamment, et j'étais sur le point de l'ajouter comme solution lorsque j'ai trouvé celle-ci. Ce n'est probablement pas le plus économique, mais c'est simple.
nize
4

Code simple avec syntaxe ES6 (retournez un tableau trié de doublons):

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

Comment utiliser:

duplicates([1,2,3,10,10,2,3,3,10]);
client
la source
1
.filter () serait beaucoup plus simple
tocqueville
4

bon mot

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

sravan ganji
la source
que fait indx!le premier exemple?
saylestyler
1
@saylestyler Hehe, cela signifie indx !== ...- une inégalité stricte.
Daria
ajout uniquement pour un tableau d'objetsresult.filter((ele,indx) => indx !== result.map(e => e.name).indexOf(ele.name));
x-magix
4

Cette réponse peut également être utile, elle exploite l' reduce opérateur / méthode js pour supprimer les doublons du tableau.

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

console.log(result);

Divyanshu Rawat
la source
3
nous pouvons maintenant juste faire new Set([1, 2, 2, 3, 3, 3, 3])pour supprimer les doublons
kimbaudi
3

La fonction suivante (une variation de la fonction éliminer les doublons déjà mentionnée) semble faire l'affaire, renvoyant test2,1,7,5 pour l'entrée ["test", "test2", "test2", 1, 1, 1, 2 , 3, 4, 5, 6, 7, 7, 10, 22, 43, 1, 5, 8]

Notez que le problème est plus étrange en JavaScript que dans la plupart des autres langues, car un tableau JavaScript peut contenir à peu près n'importe quoi. Notez que les solutions qui utilisent le tri peuvent avoir besoin de fournir une fonction de tri appropriée - je n'ai pas encore essayé cette route.

Cette implémentation particulière fonctionne pour (au moins) les chaînes et les nombres.

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;
}
Nosredna
la source
3

ES5 uniquement (c'est-à-dire qu'il a besoin d'un polyfill filter () pour IE8 et inférieur):

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] );
    });
gotofritz
la source
J'aime cette solution simple. Si vous voulez les doublons, cependant, vous devez d'abord trouver ces doublons, puis rendre la liste des doublons unique. [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])) ;});
Greg
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));

Cette fonction évite l'étape de tri et utilise la méthode Reduce () pour pousser les doublons vers un nouveau tableau s'il n'y existe pas déjà.

vasa
la source
3

C'est probablement l'un des moyens les plus rapides pour supprimer définitivement les doublons d'un tableau 10 fois plus vite que la plupart des fonctions ici. 78 fois plus rapide en safari

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. Test: http://jsperf.com/wgu
  2. Démo: http://jsfiddle.net/46S7g/
  3. Plus: https://stackoverflow.com/a/25082874/2450730

si vous ne pouvez pas lire le code ci-dessus demandez, lisez un livre javascript ou voici quelques explications sur le code plus court. https://stackoverflow.com/a/21353032/2450730

EDIT Comme indiqué dans les commentaires, cette fonction retourne un tableau avec des uniques, la question demande cependant de trouver les doublons. dans ce cas, une simple modification de cette fonction permet de pousser les doublons dans un tableau, puis l'utilisation de la fonction précédente toUniquesupprime les doublons des doublons.

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));
cocco
la source
7
"si vous ne pouvez pas lire le code ci-dessus demandez, lisez un livre javascript" Il y a trop de code golf dans cette réponse. Nommer les variables comme a, b, c rend le code difficile à lire. Oublier les accolades les aggrave.
River-Claire Williamson,
La plupart de mes réponses sont basées sur les performances et les économies d'espace (d'autres solutions sont déjà publiées) ... si vous ne l'aimez pas downvote ... sinon apprenez javascript, lisez un livre js ... ou utilisez jquery ... ils avoir beaucoup plus de réponses si vous recherchez une solution simple. Si vous voulez vraiment apprendre quelque chose, je suis heureux d'expliquer le code lettre par lettre. Comme je ne vois pas de vraie question dans votre commentaire, je suppose que vous cherchez juste un motif pour dévaloriser ma réponse ... allez-y ... je n'ai aucun problème avec ça. Posez une vraie question ou dites-moi quelque chose qui ne fonctionne pas avec mon code.
cocco
9
Il n'y a rien de mal techniquement avec votre code. Cela dit, nommer les variables a, b, c, d, etc. et enchaîner les boucles rend le code difficile à lire. Ainsi, le code n'enseigne rien.
River-Claire Williamson
3

Utiliser "comprend" pour tester si l'élément existe déjà.

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>

Srichakradhar
la source
Le code rend des éléments distincts, mais ne conduit pas au résultat donné. Veuillez fournir le code correct complet.
RWC
3

ES6 offre la structure de données Set qui est essentiellement un tableau qui n'accepte pas les doublons. Avec la structure de données Set, il existe un moyen très simple de trouver des doublons dans un tableau (en utilisant une seule boucle).

Voici mon code

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;
}
Roysh
la source
3

Je viens de trouver un moyen simple d'y parvenir en utilisant un filtre matriciel

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

alaahd
la source
3

La logique suivante sera plus facile et plus rapide

// @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));
      }

Avantages:

  1. Ligne unique :-P
  2. Toutes les structures de données intégrées aident à améliorer l'efficacité
  3. plus rapide

Description de la logique:

  1. Conversion en ensemble pour supprimer tous les doublons
  2. Itération à travers les valeurs définies
  3. Avec chaque valeur définie, vérifiez dans le tableau source la condition "les valeurs du premier index ne sont pas égales au dernier index" ==> Puis déduit comme doublon sinon il est "unique"

Remarque: les méthodes map () et filter () sont efficaces et plus rapides.

PranavKAndro
la source
1
Testé cela ... très rapidement. et c'est logique .. j'aurais aimé y penser
Michael Rhema