J'ai un tableau d'objets qui ressemble à ceci:
var array = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
...
];
Comme vous pouvez le voir, certains noms sont répétés. Je veux obtenir un nouveau tableau avec des noms uniquement, mais si un nom se répète, je ne veux pas l'ajouter à nouveau. Je veux ce tableau:
var newArray = ["Name1", "Name2"];
J'essaye de faire ça avec map
:
var newArray = array.map((a) => {
return a.name;
});
Mais le problème est que cela renvoie:
newArray = ["Name1", "Name1", "Name2", "Name2"];
Comment puis-je définir une condition à l'intérieur map
, pour qu'elle ne renvoie pas un élément qui existe déjà? Je veux faire cela avec map
ou avec une autre fonctionnalité ECMAScript 5 ou ECMAScript 6.
javascript
arrays
snoopy25
la source
la source
Set
? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Réponses:
Avec ES6, vous pouvez utiliser
Set
pour des valeurs uniques, après avoir mappé uniquement les noms des objets.Cette proposition utilise une syntaxe étalée
...
pour collecter les éléments dans un nouveau tableau.la source
...
-on?...
pour construire un tableau avec un objet itérable.Array.from
transmet beaucoup mieux l'intention de conversion (et est également plus facile à comprendre / à rechercher pour les débutants), la syntaxe de diffusion ne doit être utilisée que lorsque l'élément diffusé est l'un des nombreux. Peut-être que l'appeler une «mauvaise pratique» est un peu trop dur, désolé, j'espère juste que cela ne deviendra pas un langage courant.Si vous recherchez une solution JavaScript qui n'est pas ES 6 (pas de Set), vous pouvez utiliser la méthode Array
reduce
:la source
var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
Personnellement, je ne vois pas pourquoi tout le monde a envie d'ES 6. Si c'était mon code, je préférerais prendre en charge autant de navigateurs que possible.
la source
indexOf
-ing tout le temps? Par exemple, faireadded[name] = true
etif(added[name])
au lieu deif(a.indexOf(name))
.goto fail
, faites-vous fuir votre variable d'index dans la portée englobante, etc. etc. ES6 a été codifié dans la norme pour de bonnes raisons, et c'est pour la plupart partie trivialement facile à polyfill / transformer pour les navigateurs plus anciens.Vous pouvez aussi simplement combiner
map
avecfilter
la source
Vous pouvez utiliser Object.keys () pour obtenir le tableau des noms de propriétés énumérables propres à un objet donné à partir du résultat de l'objet de l'itération de la
array
variable avec Array.prototype.reduce () où les clés sont les noms détruitsCode:
la source
Beaucoup de bonnes réponses ici. Je voudrais juste contribuer avec une certaine diversité dans l'espoir de vous donner une autre perspective.
Les tableaux sont de type objet en JavaScript, ils peuvent donc être utilisés comme hachage en même temps. En utilisant cette fonctionnalité, nous pouvons grandement simplifier le travail à effectuer en une seule opération de réduction avec une complexité de temps O (n).
Si vous n'êtes pas satisfait du fait que votre tableau contienne des propriétés autres que les clés du tableau, vous pouvez également envisager de conserver un objet de hachage séparé.
la source
p[c.name]
truc sur un objet séparéo
, puis de le jeter par la suite.Je suis d'accord que si vous n'avez besoin que des
name
valeurs,Set
c'est la voie à suivre.Cependant , si vous souhaitez obtenir un tableau d'objets uniques en fonction de la
name
propriété, je vous suggère d'utiliser un fichierMap
. Un moyen rapide de créer une carte consiste à utiliser un tableau de[key, value]
tableaux:Un avantage supplémentaire de
Map
est que vous obtenez à la fois lafilter
fonctionnalité qui élimine les non-uniques, sans perdre la connexion avec les objets source. Bien sûr, cela n'est nécessaire que si vous avez besoin de référencer plusieurs fois l'ensemble unique d'objets.la source
Si vous êtes limité à ES5, j'utiliserais Lodash
_.uniq
la source
Avec ES6, cela devrait faire l'affaire.
la source
map
est censé être utilisé avec des fonctions pures, sans effets secondaires. Ce serait un travail pourforEach
oureduce
.En utilisant UnderscoreJS,
»
la source
Dans ES5, utilisez un objet comme dictionnaire pour les performances O ( n ).
Cela ne fonctionnera que si toutes les clés sont des chaînes.
Vous pouvez faire la même chose dans une expression si vous le souhaitez:
mais je trouve la forme impérative plus facile à lire.
la source
function (item) { return item.name; }
Object.keys()
, cette réponse utilisefilter()
pour ne conserver que les noms qui n'ont pas encore été stockés dans la carte, ce qui est assez élégant.Essaye ça:
la source
Utilisation
array#forEach()
et desarray#indexOf()
méthodes comme celle-ci si vous voulez encore une compatibilité maximale , une syntaxe concise:Cependant, si la compatibilité est pas un problème utilisation ECMAScript 6 de l »
Set
objet,array#map
et desArray.from()
méthodes comme celle - ci:la source
C'est comme ça que je l'ai fait, en utilisant un tableau vide séparé.
la source
Pour ceux qui recherchent un 1 liner
ou sans utiliser de méthodes sur le prototype du tableau
pourrait être utile pour écrire des fonctions pures pour gérer cela
la source
la source