_.union erzeugt immer Duplikate, wenn Arrays von Objekten übergeben werden.
zB _.union( [ { a:1 } ], [ { a:1 } ])
gibt [ { a:1 }, { a:1 } ]
Perverserweise sagt Ihnen die isEqual-Funktion von underscore, dass die fraglichen Objekte gleich sind. Vielleicht könnten wir ein Flag / eine Option haben, die den zu verwendenden Gleichheitsvergleich vorschreibt, oder die Option, einen Komparator zu übergeben?
Ich bin überrascht, dass es die Vergleichsfunktion nicht bereits akzeptiert. :+1:
Es ist erwähnenswert, dass dies für alle anderen Array-Berechnungsfunktionen wie Differenz, Schnittmenge, Eindeutigkeit usw. gilt.
Es wäre schön, wenn die gesamte Palette von Array-Funktionen aktualisiert werden könnte, um die Verwendung eines anderen Gleichheitskomparators für Objekte zu ermöglichen.
Wäre es nicht einfacher, wenn wir eine Option hätten, die Gleichheit basierend auf einem booleschen Parameterwert vergleicht, der an die Funktion _.union() übergeben werden könnte? Wenn es wahr ist, werden automatisch alle Objekte in diesem Array verglichen.
ZB _.union([1, 2, 3, 10, [{a:1}, {a:1}]], true)
, würde [1,2,3,10, {a:1}]
ausgeben
@amiral84 Nein. Das hat nichts damit zu
@michaelficara Dann habe ich den Sinn dieses Themas übersehen? :D
@amiral84 Es scheint so. Der Feature Request wird im ersten Kommentar ausführlich und prägnant erklärt.
das zugrunde liegende Problem scheint in _.uniq
da _.union
lediglich eine Wrapper-Funktion für Unique und Flatten ist.
_.union = restArgs(function(arrays) {
return _.uniq(flatten(arrays, true, true));
});
Dieser Thread hat mich dazu inspiriert, _.intersectionWith
, _.differenceWith
, _.unionWith
und _.uniqWith
hinzuzufügen, um Vergleichsanpassungen in meinem eigenen Code vorzunehmen.
var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];
_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]
oder etwas in der Art von _.isCollection
um festzustellen, ob es sich um eine Sammlung handelt. Wenn es sich um eine Sammlung handelt, sollten die Vergleiche _.isEqual
anstelle von ===
was bei einer Sammlung nicht gut ist.
@dperrymorrow
sollte
_.isEqual
anstelle von===
was bei einer Sammlung nicht gut ist.
Dynamisches Schalten klingt nach einer schlechten Idee. JS verwendet ===
oder SameValueZero
Vergleiche für viele Dinge. Wenn es notwendig ist, über diese Vergleiche hinauszugehen, würde etwas wie _.uniqWith
ausreichen.
Danke dafür @jdalton , die von dir erwähnten _opWith -Funktionen sind absolut perfekt für das, was ich erreichen möchte. Hast du eine Idee, wann sie per Release verfügbar sein werden?
@jdalton guter Punkt zu den Vergleichen, aber würden Sie normalerweise nicht einen Schlüssel für eine Sammlung verwenden, anstatt Underscore zu zwingen, den gesamten Unterschied zwischen den Objekten zu erkennen?
Würde das Folgende nicht die Anfrage von @wilhen01 lösen _(wenn auch ausführlicher als gewünscht)_
_.chain([{ a: 1 }]).union( [{a: 1}]).unique('a').value();
//=> [{a: 1}]
Würde das Folgende nicht die Anfrage von @wilhen01 lösen (wenn auch ausführlicher als gewünscht)
_.uniq
unterstützt das bereits.
richtig, das ist mein Punkt, der obige Code funktioniert derzeit wie gepostet.
Könnten Sie nicht einfach uniq / unique mit einem Schlüssel zum Ergebnis der Vereinigung aufrufen?
@dperrymorrow Denken Sie nur ein bisschen außerhalb dieses Beispiels und fügen Sie eine weitere Eigenschaft hinzu .
ok, gotcha, sorry ... Ich versuche nicht, streitlustig zu sein, wollte nur das Problem vollständig verstehen. Ich würde gerne eine Pull-Anfrage über die Funktion _.uniqWith
senden.
Keine Sorge, das wäre krass.
_.intersectionWith, _.differenceWith, _.unionWith und _.uniqWith
Wäre es nicht eine schönere API, die Vergleichsfunktion nur optional als letztes Argument übergeben zu können, anstatt vier neue Funktionen zu prägen?
@jaschkenas
Wäre es nicht eine schönere API, die Vergleichsfunktion nur optional als letztes Argument übergeben zu können, anstatt vier neue Funktionen zu prägen?
Ja, es könnte getan werden, aber es gibt Komplikationen, da Methoden wie _.uniq
bereits die Übergabe eines Iterierten unterstützen und auch stark mit Unterstützung für binäre / sortierte Suchflags und Kontextparameter überladen sind. Dies würde bedeuten, ein Arity-Sniffing einzuführen, das sich für diese Situation zu clever anfühlt. Dies würde auch zukünftige Modularisierungsbemühungen erschweren, da es viele optionale Funktionen an einem einzigen Punkt bündelt, wenn die Implementierungen vereinfacht und in separate Methoden aufgeteilt werden könnten.
Richtig, ein total bedauerliches Designproblem. Aber neue Funktionen zu entwickeln, nur um einen Komparator zu ermöglichen, fühlt sich auch nicht nach der richtigen Lösung an.
ok, also sind hier zusätzliche Vergleichsfunktionsparameter der richtige Weg?
Wenn ja, kann ich meine Pull-Anfrage aktualisieren.
Der einzige knifflige Teil, den ich sehe, besteht darin, das Parameter-Parsing etwas haariger zu machen, wie oben bei @jdalton erwähnt.
_.uniq = _.unique = function(array, isSorted, iteratee, context) {
if (!_.isBoolean(isSorted)) {
context = iteratee;
iteratee = isSorted;
isSorted = false;
}
//...
Vielleicht fügen Sie eine zusätzliche Prüfung hinzu, um zu sehen, ob isSorted _.isFunction
und behandeln Sie es dann als Komparator.
@jaschkenas
Aber neue Funktionen zu entwickeln, nur um einen Komparator zu ermöglichen, fühlt sich auch nicht nach der richtigen Lösung an.
Es kann die beste Option für eine schlechte Situation sein. Ich habe in letzter Zeit überladene Funktionen abgespalten und bin mit dem Ergebnis ziemlich zufrieden. Obwohl es die API-Oberfläche vergrößert, ermöglicht es einfachere Implementierungen und Gruppierungen ähnlicher Methoden wie maxBy
, uniqBy
, pickBy
oder uniqWith
, unionWith
, zipWith
oder sortedIndexBy
, sortedIndexOf
, sortedUniq
. Im Fall von uniq
nutze ich derzeit allerdings noch eine Shared-Base-Funktion.
haben diesen Pull-Request #2368 aktualisiert danke.
Ich bin :+1: für uniqBy
oder uniqWith
. Ich wäre absolut dagegen, uniq
weiter zu überladen (wie derzeit #2368 vorgeschlagen wird)
:+1: @megawac , uniqBy
.
Fwiw lodash wird uniqBy
als aufgeteiltes Formular von _.uniq(array, iteratee)
und _.uniqWith
als Formular verwenden, um die Anpassung des Komparators zu ermöglichen.
Ja, auf den zweiten Gedanken ist uniqWith
ein besserer Name
sollte ich dann mit der separaten Methode eine Anfrage auf Lodash ziehen?
Ich dachte, die beiden Projekte würden zusammengeführt, irre ich mich?
@dperrymorrow
sollte ich dann mit der separaten Methode eine Anfrage an Lodash ziehen?
Keine Notwendigkeit, sie sind bereits im Edge-Master-Zweig von Lodash.
Ich dachte, die beiden Projekte würden zusammengeführt, irre ich mich?
Noch nicht. Lodash v4 beweist jedoch einige der Ideen der Zusammenführung.
@jdalton Können Sie bitte etwas mehr über die Implementierung von _.uniqWith
mit anderen Iterierten ausführen.
@Pavnii
Sicher. Sie können sich lodash/npm/_baseUniq ansehen .
Wenn ein comparator
wird, verwendet es den arrayIncludesWith
Helfer um die Prüfung statt arrayIncludes
durchzuführen (Unterstrich ist contains
).
@jdalton Das hilft mir.
Hilfreichster Kommentar
Dieser Thread hat mich dazu inspiriert,
_.intersectionWith
,_.differenceWith
,_.unionWith
und_.uniqWith
hinzuzufügen, um Vergleichsanpassungen in meinem eigenen Code vorzunehmen.