Disons que je commence par ceci:
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"
}];
J'utilise ceci pour pré-remplir un formulaire. Les utilisateurs peuvent modifier des entrées ou en ajouter de nouvelles. Je dois les empêcher d'ajouter des doublons.
Le problème est que la structure du formulaire que je sérialise et l'ordre dans lequel ces valeurs sont renvoyées de la base de données ne sont pas les mêmes. Il est donc possible que j'insère un élément dans ce tableau au format suivant:
{
"country": "US",
"firstname": "Kevin",
"lastname": "Borders",
"address1": "2201 N Pershing Dr",
"address2": "Apt 417",
"Zip": "22201",
"city": "Arlington",
"state": "VA"
}
Ce qui est identique à la première entrée, vient d’être commandé différemment.
Je charge des underscorejs, alors s’il est possible de gérer cela avec cette bibliothèque, ce serait génial. J'utilise aussi jQuery si cela aide.
À ce stade, je ne sais pas comment procéder.
La fonction Underscore findWhere
fait exactement ce dont vous avez besoin - ce n'est pas une recherche indexOf
par identité d'objet, mais recherche des objets dont les propriétés ont les mêmes valeurs que l'entrée.
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>
Bien que cela ne réponde pas directement à la question, cela répond à la question plus générale de savoir comment ajouter des valeurs uniques à un tableau, et comme moi, d'autres pourraient tomber sur cette page de Google.
sur la base de cette réponse à: "js-remove-an-array-element-by-index-in-javascript"
https://stackoverflow.com/a/7142909/886092
J'utilise l'idiome suivant qui est concis et ne nécessite pas underscore.js ou tout autre framework.
Voici un exemple d’enregistrement de lignes sélectionnées et non sélectionnées pour DataTables jquery plugin . Je conserve un tableau des identifiants actuellement sélectionnés et je ne souhaite pas avoir de doublons dans le tableau:
en 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)
Plus généralement ce serait
position = myArray.indexOf(myval)
unless ~position
myArray.Push myVal
ou en JS
var position;
position = myArray.indexOf(myval);
if (!~position) {
myArray.Push(myVal);
}
EDIT, cela fonctionnera avec votre exemple de propriétés non triées:
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});
et nous pourrions faire cela avec un one-liner mais ce serait super laid:
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});
Si vous voulez vérifier l'objet d'entrée utilisateur, vous pouvez essayer cette fonction:
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");
}
});
}
Et essayez d’appeler cette fonction de vérification dans un paramètre différent (uniqueInput et duplicatedInput).
checkDuplication(uniqueInput,shippingAddresses);
checkDuplication(duplicatedInput,shippingAddresses);
Je fais un jsfiddle . Vous pouvez l'essayer… .. espérons que cela vous soit utile.
Exemple de base utilisant Set()
à partir de ECMAScript 2015
L'objet Set
vous permet de stocker des valeurs uniques de tout type (qu'il s'agisse de valeurs primitives ou de références d'objet). Si un objet iterable est passé, tous ses éléments seront ajoutés à la nouvelle Set
. Ici, je vais juste ajouter une valeur:
// 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]