Rufen Sie eine Liste doppelter Objekte in einem Array von Objekten ab

Lesezeit: 6 Minuten

Benutzer-Avatar
josh_boaz

Ich versuche, doppelte Objekte in einem Array von Objekten zu erhalten. Nehmen wir an, das Objekt ist wie unten.

values = [
  { id: 10, name: 'someName1' },
  { id: 10, name: 'someName2' },
  { id: 11, name: 'someName3' },
  { id: 12, name: 'someName4' }
];

Doppelte Objekte sollten wie folgt zurückgegeben werden:

duplicate = [
  { id: 10, name: 'someName1' },
  { id: 10, name: 'someName2' }
];

  • Und was ist Ihre Frage?

    – ssc-hrep3

    8. November 2018 um 16:30 Uhr

  • Probieren wie? Sie haben uns keinen Code gezeigt, der versucht, dieses Problem zu lösen. Eine Websuche nach Array-Duplikaten sollte Ihnen einen guten Ausgangspunkt bieten

    – charlietfl

    8. November 2018 um 16:31 Uhr


Benutzer-Avatar
ggorlen

Sie können verwenden Array#reduce um eine Zähler-Nachschlagetabelle basierend auf dem zu erstellen id Schlüssel, dann verwenden Array#filter um alle Elemente zu entfernen, die nur einmal in der Nachschlagetabelle erschienen sind. Die Zeitkomplexität ist O(n).

const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];

const lookup = values.reduce((a, e) => {
  a[e.id] = ++a[e.id] || 0;
  return a;
}, {});

console.log(values.filter(e => lookup[e.id]));

  • Können Sie bitte Ihren Code erklären? Ich verwirre. Sie haben keine Gleichheit in Ihrem Code, wie das funktioniert? Und warum a Zeigen Sie in jeder Iteration dasselbe Objekt? Ich benötige eine detaillierte Analyse Ihres Codes.

    – Spektr

    6. Februar 2020 um 8:13 Uhr


  • Ich empfehle, einen Blick in die Dokumentation zu werfen reduce und filter falls noch nicht geschehen. ich benutze reduce um eine Objektabbildung von jedem Objekt zu erstellen id zur Zählung seiner occurrences - 1. a ist das Akkumulator-Objekt, das von einem Callback zum nächsten übergeben wird reduce. filter verwendet die Wahrhaftigkeit von lookup[e.id] um festzustellen, ob ein Element eindeutig ist. Wenn der Lookup-Eintrag 0 (falsey) ist, wurde er nur einmal gesehen und filter lässt es aus der Ergebnismenge weg, andernfalls wird es beibehalten.

    – ggorlen

    6. Februar 2020 um 8:23 Uhr


  • Eigentlich kenne ich mich mit Reduce (kein Experte, aber weiß) und Filter aus. Und weiß, wie sie funktionieren. Aber es ist zu schwer, Ihren Code zu verstehen. Aber mit Ihrer Erklärung ist alles ein bisschen einfacher geworden 🙂 Danke.

    – Spektr

    6. Februar 2020 um 8:33 Uhr


  • Dies ist ein äußerst cleverer Code, und ich glaube nicht, dass Ihre Erklärung dem gerecht wird @ggorlen ! Um genau zu erklären, was innerhalb des Reduzierens vor sich geht, hier Folgendes: Jedes Element im Array wird von der Pfeilfunktion verarbeitet und erstellt entweder eine Eigenschaft in der Suche (neues Element) oder erhöht den Zähler (wir haben ein Duplikat gefunden). Genau wie das funktioniert ist wie folgt: a[e.id] = ++a[e.id] || 0 erhöht eine Eigenschaft nur dann mit ++, wenn sie bereits vorhanden ist. Wenn dies nicht der Fall ist, fällt es durch das ODER (||) und erstellt eine Eigenschaft mit dem Wert 0.

    – hevans900

    15. Juli 2021 um 15:02 Uhr


  • @ggorlen Können wir mehrere Felder ID und Name vergleichen?

    – Vivek

    16. Juli 2021 um 15:18 Uhr

Benutzer-Avatar
HMagdy

Nehmen wir an, Sie haben:

arr = [
    { id:10, name: 'someName1' },
    { id:10, name: 'someName2' },
    { id:11, name: 'someName3' },
    { id:12, name: 'someName4' }
]

Um einzigartige Gegenstände zu erhalten:

unique = arr
     .map(e => e['id'])
     .map((e, i, final) => final.indexOf(e) === i && i)
     .filter(obj=> arr[obj])
     .map(e => arr[e]);

Dann wird das Ergebnis sein

unique = [
     { id:10, name: 'someName1' },
     { id:11, name: 'someName3' },
     { id:12, name: 'someName4' }
]

Und um doppelte IDs zu erhalten:

duplicateIds = arr
     .map(e => e['id'])
     .map((e, i, final) => final.indexOf(e) !== i && i)
     .filter(obj=> arr[obj])
     .map(e => arr[e]["id"])

Liste der IDs wird sein

duplicateIds = [10]

Um also doppelte Objekte zu erhalten:

duplicate = arr.filter(obj=> dublicateIds.includes(obj.id));

Jetzt hast du es:

duplicate = [
    { id:10, name: 'someName1' },
    { id:10, name: 'someName2' }
]

Vielen Dank https://reactgo.com/removeduplicateobjects/

  • Wie finden wir Duplikate für mehrere Eigenschaften heraus?

    – Vivek

    19. Juli 2021 um 8:14 Uhr

  • Ich bin nicht, was meinst du @Vivek, wenn du Beispiele für die Eingaben und die erwartete Ausgabe hast, kann ich dir helfen!

    – HMagdy

    20. Juli 2021 um 9:44 Uhr


  • Danke, dass Sie zurückgekommen sind. Ich verwende in Ihrer Antwort genau dasselbe Beispiel. In Ihren Beispielen finden wir Duplikate anhand der ID heraus. Wenn wir doppelte ID- und Namenseigenschaften herausfinden müssen, welche Änderungen müssen vorgenommen werden? jede Hilfe wäre willkommen

    – Vivek

    20. Juli 2021 um 10:52 Uhr

  • Sie können das einfach tun, indem Sie “.map(e => e[‘id’])” durch “.map(e => e[‘id’]+’_’+e[‘name’])”

    – HMagdy

    22. Juli 2021 um 11:50 Uhr

  • Und wie nennen wir es?

    – Vivek

    23. Juli 2021 um 15:14 Uhr

Sie haben nicht geklärt, ob zwei Objekte mit unterschiedlichen IDs, aber demselben “Namen” als Duplikat gelten. Ich gehe davon aus, dass diese nicht als Duplikat zählen; Mit anderen Worten, nur Objekte mit derselben ID zählen als Duplikate.

let ids = {};
let dups = [];

values.forEach((val)=> {
  if (ids[val.id]) {
    // we have already found this same id
    dups.push(val)
  } else {
    ids[val.id] = true;
  }
})
return dups;

Benutzer-Avatar
Akrion

Mit lodash können Sie dies lösen filter und countBy für Komplexität von O(n):

const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]

const counts = _.countBy(data, 'id')
console.log(_.filter(data, x => counts[x.id] > 1))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Sie könnten dasselbe mit ES6 so machen:

const data = [{ id: 10,name: 'someName1' }, { id: 10,name: 'someName2' }, { id: 11,name: 'someName3' }, { id: 12,name: 'someName4' } ]

const countBy = (d, id) => d.reduce((r,{id},i,a) => (r[id] = a.filter(x => x.id == id).length, r),{})
const counts = countBy(data, 'id')
console.log(data.filter(x => [x.id] > 1))

Sie können ein Array verwenden, um eindeutige Elemente zu speichern, und Filter für Werte verwenden, um nur Duplikate zurückzugeben.

const unique = []

const duplicates = values.filter(o => {

   if(unique.find(i => i.id === o.id && i.name === o.name)) {
     return true
   }

   unique.push(o)
   return false;
})

Mit lodash können Sie verwenden _.groupBy() um Elemente nach ihrer zu gruppieren id. Als _.filter() aus Gruppen, die weniger als zwei Mitglieder haben, und _.flatten() die Ergebnisse:

const values = [{id: 10, name: 'someName1'}, {id: 10, name: 'someName2'}, {id: 11, name:'someName3'}, {id: 12, name: 'someName4'}];

const result = _.flow([
  arr => _.groupBy(arr, 'id'), // group elements by id
  g => _.filter(g, o => o.length > 1), // remove groups that have less than two members
  _.flatten // flatten the results to a single array
])(values);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Benutzer-Avatar
Cassio Lacerda

Eine Alternative basierend auf @ggorlen-Lösung mit neuer Map() als Akkumulator (für bessere Leistung) und ohne unären Operator ++ (nicht standardmäßig in Projekten mit ESLint empfohlen).

const values = [{ id: 10, name: "someName1" }, { id: 10, name: "someName2" }, { id: 11, name: "someName3" }, { id: 12, name: "someName4" },];

const lookup = values.reduce((a, e) => {
  a.set(e.id, (a.get(e.id) ?? 0) + 1);
  return a;
}, new Map());

console.log(values.filter(e => lookup.get(e.id) > 1));

1011360cookie-checkRufen Sie eine Liste doppelter Objekte in einem Array von Objekten ab

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy