Si tengo una serie de cadenas, puedo usar el .join()
método para obtener una sola cadena, con cada elemento separado por comas, así:
["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"
Tengo una serie de objetos y me gustaría realizar una operación similar en un valor contenido en él; entonces de
[
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
]
realice el join
método solo en el name
atributo, para lograr el mismo resultado que antes.
Actualmente tengo la siguiente función:
function joinObj(a, attr){
var out = [];
for (var i = 0; i < a.length; i++){
out.push(a[i][attr]);
}
return out.join(", ");
}
No hay nada de malo en ese código, funciona, pero de repente he pasado de una línea de código simple y sucinta a una función muy imperativa. ¿Existe una forma más sucinta, idealmente más funcional de escribir esto?
javascript
arrays
object
Jackweirdy
fuente
fuente
" ,".join([i.name for i in a])
users.map(x => x.name).join(', ');
.Respuestas:
Si desea asignar objetos a algo (en este caso, una propiedad). Creo que
Array.prototype.map
es lo que estás buscando si quieres codificar funcionalmente.En JavaScript moderno:
(violín)
Si desea admitir navegadores más antiguos, que no son compatibles con ES5 , puede calzarlo (hay un polyfill en la página MDN anterior). Otra alternativa sería utilizar el
pluck
método underscorejs :fuente
[x.name for x of users]
(spec wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions ). Vale la pena mencionar que al igual que usar map / reduce / filter no es muy 'pitónico', la otra forma probablemente se cumple en JavaScript. CoffeeScript es genial con ellos aunque coffeescript.org .users.map((obj) -> obj.name).join(', ')
Bueno, siempre puedes anular el
toString
método de tus objetos:fuente
toString
método de todos los elementos, utilizando un bucle for. O podría usar este enfoque cuando trabaje con funciones de constructor, agregando untoString
método a laprototype
propiedad para el constructor. Sin embargo, se suponía que este ejemplo mostraba el concepto básico.También me he encontrado con el
reduce
método, así es como se ve:El
(a.name || a)
es por lo que el primer elemento se trata correctamente, pero el resto (en la quea
es una cadena, y asía.name
no está definida) no se trata como un objeto.Editar: ahora lo he refactorizado para esto:
que creo que es más limpio, ya
a
que siempre es una cadena,b
siempre es un objeto (debido al uso del parámetro initialValue opcional enreduce
)Editar 6 meses después: Oh, qué estaba pensando. "limpiador". He enojado el código Dioses.
fuente
reduce
no es tan ampliamente compatible comomap
(lo cual es extraño, dado que son como hermanas), así que todavía estoy usando tu respuesta :)No sé si hay una manera más fácil de hacerlo sin usar una biblioteca externa, pero personalmente me encanta underscore.js, que tiene toneladas de utilidades para manejar matrices, colecciones, etc.
Con el guión bajo, puede hacer esto fácilmente con una línea de código:
_.pluck(arr, 'name').join(', ')
fuente
arr
está su matriz, naturalmente?)En nodo o ES6 +:
fuente
digamos que la matriz hace referencia a la matriz de objetos
users
Si se puede usar ES6, la solución más fácil será:
Si no, y lodash se puede usar para:
fuente
Si objeto y claves dinámicas:
"applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
fuente
Un viejo hilo que conozco pero que sigue siendo súper relevante para cualquiera que se encuentre con esto.
Array.map ha sido sugerido aquí, que es un método increíble que uso todo el tiempo. Array.reduce también fue mencionado ...
Yo personalmente usaría un Array.reduce para este caso de uso. ¿Por qué? A pesar de que el código es un poco menos limpio / claro. Es mucho más eficiente que canalizar la función del mapa a una unión.
La razón de esto es porque Array.map tiene que recorrer cada elemento para devolver una nueva matriz con todos los nombres del objeto en la matriz. Array.join luego recorre el contenido de la matriz para realizar la unión.
Puede mejorar la legibilidad de jackweirdys para reducir la respuesta utilizando literales de plantilla para obtener el código en una sola línea. "Compatible con todos los navegadores modernos también"
fuente
No estoy seguro, pero todo esto responde que funcionan, pero no son óptimos, ya que están realizando dos escaneos y puede hacerlo en un solo escaneo. Aunque O (2n) se considera O (n) siempre es mejor tener un O (n) verdadero.
Esto podría parecerse a la vieja escuela, pero me permite hacer cosas así:
fuente
prueba esto
fuente
name
atributo. (a[i].name
No no utilizar su función dename
argumento, que es equivalente aa[i]['name']
.)