Tengo una matriz de objetos que se parece a esto:
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"}
...
];
Como puede ver, se repiten algunos nombres. Quiero obtener una nueva matriz solo con nombres, pero si algún nombre se repite, no quiero volver a agregarlo. Quiero esta matriz:
var newArray = ["Name1", "Name2"];
Estoy tratando de hacer esto con map
:
var newArray = array.map((a) => {
return a.name;
});
Pero el problema es que esto vuelve:
newArray = ["Name1", "Name1", "Name2", "Name2"];
¿Cómo puedo establecer alguna condición interna map
para que no devuelva un elemento que ya existe? Quiero hacer esto con map
o alguna otra característica de ECMAScript 5 o ECMAScript 6.
javascript
arrays
snoopy25
fuente
fuente
Set
? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Respuestas:
Con ES6, puede utilizar
Set
para valores únicos, después de asignar solo los nombres de los objetos.Esta propuesta utiliza una sintaxis de extensión
...
para recopilar los elementos en una nueva matriz.fuente
...
?...
para construir una matriz con un objeto iterable.Array.from
transmite la intención de conversión mucho mejor (y también es más fácil de entender / buscar novatos), la sintaxis de propagación debe usarse solo cuando el elemento de propagación sea uno de muchos. Quizás llamarlo "mala práctica" sea un poco duro, lo siento, solo espero evitar que se convierta en un modismo común.Si está buscando una solución de JavaScript que no sea ES 6 (no Set), puede usar el método de Array
reduce
:fuente
var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
Personalmente, no veo por qué todo el mundo se está volviendo elegante con ES 6. Si fuera mi código, preferiría admitir tantos navegadores como sea posible.
fuente
indexOf
-ing todo el tiempo? Por ejemplo, haceradded[name] = true
y enif(added[name])
lugar deif(a.indexOf(name))
.goto fail
, filtrando su variable de índice en el alcance adjunto, etc. etc. ES6 fue codificado en el estándar por buenas razones, y es para la mayoría parte trivialmente fácil de rellenar / transformar para navegadores más antiguos.También puedes simplemente combinar
map
confilter
fuente
Puede usar Object.keys () para obtener la matriz de los nombres de propiedad enumerables propios de un objeto dado del resultado del objeto de la
array
variable iterativa con Array.prototype.reduce () donde las claves son los nombres destruidosCódigo:
fuente
Muchas buenas respuestas aquí. Solo me gustaría contribuir con algo de diversidad con la esperanza de darles otra perspectiva.
Las matrices son del tipo de objeto en JavaScript, por lo que se pueden usar como hash al mismo tiempo. Al utilizar esta funcionalidad, podemos simplificar enormemente el trabajo a realizar en una sola operación de reducción con una complejidad de tiempo O (n).
Si no está satisfecho con que su matriz tenga algunas propiedades distintas de las claves de la matriz, podría considerar mantener un objeto hash separado también.
fuente
p[c.name]
cosas en un objeto separadoo
y luego desecharlo.Estoy de acuerdo en que si solo necesita los
name
valores, aSet
es el camino a seguir.Sin embargo , si desea obtener una matriz de objetos únicos basados en la
name
propiedad, le sugiero que use un archivoMap
. Una forma rápida de crear un mapa es a través de una matriz de[key, value]
matrices:Un beneficio adicional
Map
es que obtiene lafilter
funcionalidad que elimina los no únicos, sin perder la conexión con los objetos de origen. Por supuesto, solo es necesario si necesita hacer referencia al conjunto único de objetos varias veces.fuente
Si está limitado a ES5, usaría Lodash's
_.uniq
fuente
Con ES6 esto debería funcionar.
fuente
map
se supone que debe usarse con funciones puras, no para tener efectos secundarios. Este sería un trabajo paraforEach
oreduce
.Usando UnderscoreJS,
'
fuente
En ES5, use un objeto como diccionario para el rendimiento de O ( n ).
Esto solo funcionará si todas las claves son cadenas.
Puede hacer lo mismo en una expresión si lo desea:
pero encuentro la forma imperativa más fácil de leer.
fuente
function (item) { return item.name; }
Object.keys()
, esta respuesta utilizafilter()
para mantener solo aquellos nombres que aún no se han almacenado en el mapa, lo cual es bastante elegante.Prueba esto:
fuente
Utilice métodos
array#forEach()
yarray#indexOf()
como este si desea la máxima compatibilidad , sintaxis concisa:Sin embargo, si la compatibilidad es no es un problema uso ECMAScript 6 's
Set
de objeto,array#map
yArray.from()
métodos como este:fuente
Así es como lo hice, usando una matriz vacía separada.
fuente
Para aquellos que buscan un delineador 1
o sin usar métodos en el prototipo de la matriz
podría ser útil para escribir algunas funciones puras para lidiar con esto
fuente
fuente