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 constater, certains noms sont répétés. Je veux obtenir un nouveau tableau avec des noms uniquement, mais si certains noms se répètent, je ne veux pas l'ajouter à nouveau. Je veux ce tableau:
var newArray = ["Name1", "Name2"];
J'essaie de faire cela avec map
:
var newArray = array.map((a) => {
return a.name;
});
Mais le problème est que cela retourne:
newArray = ["Name1", "Name1", "Name2", "Name2"];
Comment puis-je définir une condition dans map
, afin qu'elle ne retourne pas un élément qui existe déjà? Je souhaite effectuer cette opération avec map
ou une autre fonction ECMAScript 5 ou ECMAScript 6.
Avec ES6, vous pouvez utiliser Set
pour des valeurs uniques, après avoir mappé uniquement les noms des objets.
Cette proposition utilise une syntaxe spread ...
pour collecter les éléments dans un nouveau tableau.
const 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" }],
names = [...new Set(array.map(a => a.name))];
console.log(names);
Si vous recherchez une solution JavaScript autre que ES 6 (pas de set), vous pouvez utiliser la méthode reduce
de Array :
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"}
];
var names = array.reduce(function (a, b) {
if (a.indexOf(b.name) == -1) {
a.Push(b.name)
}
return a;
}, []);
console.log(names);
Personnellement, je ne vois pas pourquoi tout le monde s'emballe avec ES 6. Si c'était mon code, je préférerais supporter autant de navigateurs que possible.
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"}
];
// Create array of unique names
var a = (function(a){
for (var i = array.length; i--;)
if (a.indexOf(array[i].name) < 0) a.Push(array[i].name);
return a;
})([]);
console.log(a);
Vous pouvez également simplement combiner map
avec filter
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"}
];
var unique = array
.map( item => item.name )
.filter( ( item, idx, arr ) => arr.indexOf( item ) == idx )
console.log(unique)
Vous pouvez faire Array.prototype.map () pour obtenir un tableau avec les propriétés name
et/ Array.prototype.filter () en utilisant les paramètres elem
, index
et array
, dans le prédicat de fonction pour éliminer les éléments répétés:
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"}],
names = array
.map(e => e.name)
.filter((e, i, a) => a.indexOf(e) === i);
console.log(names);
Je conviens que si vous avez uniquement besoin des valeurs name
, une Set
est la voie à suivre.
Cependant, si vous souhaitez obtenir un tableau d'objets uniques basé sur la propriété name
, il est conseillé d'utiliser un Map
. Un moyen rapide de créer une carte consiste à utiliser un tableau de tableaux [key, value]
:
const 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" }],
unique = new Map(array.map(obj => [obj.name, obj]));
// To get the unique objects
const uniques = Array.from(unique.values());
// Get the names like you already did:
console.log("Names:", uniques.map(obj => obj.name));
// If you ever need the complete array of unique objects, you got a ref:
console.log(JSON.stringify(uniques));
.as-console-wrapper { min-height: 100%; }
Un avantage supplémentaire de Map
est que vous obtenez à la fois la fonctionnalité filter
qui supprime les non-uniques, sans perdre la connexion avec les objets source. Bien sûr, cela n'est nécessaire que si vous devez référencer plusieurs fois le jeu d'objets unique.
Beaucoup de bonnes réponses ici. Je voudrais juste contribuer avec une certaine diversité en espérant vous donner une autre perspective.
Les tableaux sont de type objet en JavaScript, ils peuvent donc être utilisés simultanément comme hachage. 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 votre tableau ne contient pas certaines propriétés autres que les clés de tableau, vous pouvez également envisager de conserver un objet de hachage distinct.
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"}
],
result = array.reduce((p,c) => p[c.name] ? p : (p[c.name] = true, p.Push(c.name), p), []);
console.log(result);
Si vous êtes limité à ES5, je voudrais utiliser Le _.uniq
de Lodash
var newArray = _.uniq(array.map(function(a) {
return a.name;
}));
Avec ES6, cela devrait faire l'affaire.
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"}
];
var set = new Set();
array.forEach((a)=>{
set.add(a.name);
});
console.log(Array.from(set));
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.
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"}
];
var allNames = array.map(item => item.name);
var map = {};
allNames.forEach(name => {
map[name] = true;
});
var uniqueNames = Object.keys(map);
console.log(uniqueNames);
Vous pouvez faire la même chose en une seule expression si vous aimez:
var uniqueNames = Object.keys(allNames.reduce((m, n) => (m[n] = true, m), {}));
mais je trouve la forme impérative plus facile à lire.
En utilisant UnderscoreJS,
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"}];
get_names = _.pluck(_.uniq(array, 'name'), 'name')
console.log(get_names)
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
`
Essaye ça:
nArr = [];
array.forEach((a) => {
if (nArr.indexOf(a.name) < 0) {
nArr.Push(a.name);
}
});
C'est comme ça que je l'ai fait, en utilisant un tableau vide séparé.
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"}
];
var array2 = []
for (i=0; i<array.length;i++){
if (array2.indexOf(array[i].name) == -1){
array2.Push(array[i].name);
}
}
console.log(array2)