Nehmen wir an, ich fange damit an:
var shippingAddresses = [{
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"Zip": "22201",
"country": "US"
}, {
"firstname": "Dan",
"lastname": "Hess",
"address1": "304 Riversedge Dr",
"address2": "",
"city": "Saline",
"state": "MI",
"Zip": "48176",
"country": "US"
}];
Ich benutze dies, um ein Formular vorzufüllen. Benutzer können Einträge bearbeiten oder neue hinzufügen. Ich muss verhindern, dass sie Duplikate hinzufügen.
Das Problem ist, dass die Struktur des Formulars, das ich serialisiere, und die Reihenfolge, in der diese Werte von der Datenbank zurückgegeben werden, nicht identisch sind. Daher besteht die Möglichkeit, dass ich ein Element mit folgendem Format in dieses Array einfügen:
{
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"Zip": "22201",
"city": "Arlington",
"state": "VA"
}
Welches ist das gleiche wie der erste Eintrag, nur anders geordnet.
Ich lade Unterstriche, also, wenn es einen Weg gibt, mit dieser Bibliothek umzugehen, wäre das großartig. Ich verwende auch jQuery, wenn das hilft.
An diesem Punkt bin ich nicht sicher, wie ich vorgehen soll.
Die Underscore findWhere
-Funktion macht genau das, was Sie brauchen - es ist keine indexOf
-Suche nach Objektidentität, sondern durchsucht Objekte, deren Eigenschaften dieselben Werte wie die Eingabe haben.
if (_.findWhere(shippingAddresses, toBeInserted) == null) {
shippingAddresses.Push(toBeInserted);
}
var a = [1,2,3];
// try to add "1" and "4" to the above Array
a = _.union(a, [1, 4]);
console.log(a);
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
Dies beantwortet zwar nicht direkt die Frage, aber es beantwortet auch die weiter gefasste Frage, wie einem Array eindeutige Werte hinzugefügt werden sollen. Wie ich, könnten andere auf diese Seite von Google stoßen.
basierend auf dieser Antwort auf: "js-remove-an-array-element-by-index-in-javascript"
https://stackoverflow.com/a/7142909/886092
Ich verwende die folgende Redewendung, die kurz ist und keine Underscore.js oder andere Frameworks erfordert.
Hier ist ein Beispiel für die Aufnahme ausgewählter und nicht markierter Zeilen für das DataTables-Jquery-Plugin . Ich behalte ein Array mit aktuell ausgewählten IDs und möchte nicht mit Duplikaten im Array enden:
in coffeescript
fnRowSelected: (nodes) ->
position = $selected.indexOf(nodes[0].id)
unless ~position
$selected.Push nodes[0].id
return
fnRowDeselected: (nodes) ->
position = $selected.indexOf(nodes[0].id)
if ~position
$selected.splice(position, 1)
Allgemeiner wäre es
position = myArray.indexOf(myval)
unless ~position
myArray.Push myVal
oder in JS
var position;
position = myArray.indexOf(myval);
if (!~position) {
myArray.Push(myVal);
}
BEARBEITEN, dies funktioniert mit Ihrem Beispiel für unsortierte Eigenschaften:
var normalized_array = _.map(shippingAddresses, function(a){
var o = {};
_.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]});
return o;
})
var stringy_array = _.map(normalized_array, JSON.stringify);
shippingAddresses = _.map(_.uniq(stringy_array), JSON.parse});
und wir könnten das mit einem Einzeiler machen, aber es wäre super hässlich:
shippingAddresses_uniq = _.map(_.uniq(_.map(_.map(shippingAddresses, function(a){ var o = {}; _.each(Object.keys(shippingAddresses[0]), function(x){o[x] = a[x]}); return o; }), JSON.stringify)), JSON.parse});
Wenn Sie das Benutzereingabeobjekt überprüfen möchten, können Sie diese Funktion ausprobieren:
var uniqueInput = {
"country": "UK",
"firstname": "Calvin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"Zip": "22201"
};
var duplicatedInput = {
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"Zip": "22201"
};
var shippingAddresses = [{
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"city": "Arlington",
"state": "VA",
"Zip": "22201",
"country": "US"
}, {
"firstname": "Dan",
"lastname": "Hess",
"address1": "304 Riversedge Dr",
"address2": "",
"city": "Saline",
"state": "MI",
"Zip": "48176",
"country": "US"
}];
function checkDuplication(checkTarget,source){
_.each(source,function(obj){
if(_.isEqual(checkTarget,obj)){
alert("duplicated");
}
});
}
Versuchen Sie, diese Überprüfungsfunktion in verschiedenen Parametern aufzurufen (uniqueInput und duplicatedInput) Ich denke, es könnte die Duplizierungseingabe in Ihren Versandadressen überprüfen.
checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);
Ich mache eine jsfiddle . Sie könnten es versuchen ... Ich hoffe, das ist hilfreich für Sie.
Einfaches Beispiel mit Set()
aus ECMAScript 2015
Mit dem Objekt Set
können Sie eindeutige Werte eines beliebigen Typs speichern (ob Grundwerte oder Objektreferenzen). Wenn ein iterierbares Objekt übergeben wird, werden alle Elemente der neuen Set
hinzugefügt. Hier füge ich nur einen Wert hinzu:
// Use Set to remove duplicate elements from the array
// and keep your new addition from causing a duplicate
const numbers = [1, 1, 1, 2, 3, 100]
// existing value is not added since it exists (and array is de-duped)
console.log(Array.from(new Set([...numbers, 100])))
// [1, 2, 3, 100]
// non-existing value is added (and array is de-duped)
console.log(Array.from(new Set([...numbers, 101])))
// [1, 2, 3, 100, 101]