Se eu tiver uma matriz de cadeias, posso usar o .join()
método para obter uma única cadeia, com cada elemento separado por vírgulas, assim:
["Joe", "Kevin", "Peter"].join(", ") // => "Joe, Kevin, Peter"
Eu tenho uma matriz de objetos e gostaria de executar uma operação semelhante em um valor mantido dentro dela; então de
[
{name: "Joe", age: 22},
{name: "Kevin", age: 24},
{name: "Peter", age: 21}
]
execute o join
método apenas no name
atributo, para obter a mesma saída de antes.
Atualmente, tenho a seguinte função:
function joinObj(a, attr){
var out = [];
for (var i = 0; i < a.length; i++){
out.push(a[i][attr]);
}
return out.join(", ");
}
Não há nada errado com esse código, ele funciona, mas de repente eu passei de uma linha simples e sucinta de código para uma função muito imperativa. Existe uma maneira mais sucinta e idealmente mais funcional de escrever isso?
javascript
arrays
object
jackweirdy
fonte
fonte
" ,".join([i.name for i in a])
users.map(x => x.name).join(', ');
.Respostas:
Se você deseja mapear objetos para algo (neste caso, uma propriedade). Eu acho
Array.prototype.map
que é o que você está procurando se quiser codificar funcionalmente.No JavaScript moderno:
(violino)
Se você deseja oferecer suporte a navegadores mais antigos, que não sejam compatíveis com o ES5, pode alterá-lo (existe um polyfill na página MDN acima). Outra alternativa seria usar o
pluck
método do underscorejs :fonte
[x.name for x of users]
(espec wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions ). Vale ressaltar que, assim como usar o mapa / reduzir / filtrar, não é muito "pitônico", o contrário provavelmente ocorre no JavaScript. O CoffeeScript é legal com eles no coffeescript.org .users.map((obj) -> obj.name).join(', ')
Bem, você sempre pode substituir o
toString
método de seus objetos:fonte
toString
método de todos os itens, usando um loop for. Ou você pode usar essa abordagem ao lidar com funções do construtor, adicionando umtoString
método àprototype
propriedade do construtor. Este exemplo, no entanto, deveria apenas mostrar o conceito básico.Eu também me deparei com o
reduce
método, é o que parece:O
(a.name || a)
é assim que o primeiro elemento é tratado corretamente, mas o restante (ondea
é uma string e, portanto,a.name
é indefinido) não é tratado como um objeto.Edit: Eu agora refatorei ainda mais isso:
que eu acredito que é mais limpo, como
a
sempre é uma string,b
é sempre um objeto (devido ao uso do parâmetro initialValue opcional emreduce
)Editar 6 meses depois: Oh, o que eu estava pensando? "limpador". Eu irritei o código deuses.
fonte
reduce
não é tão amplamente apoiada, comomap
(o que é estranho, uma vez que eles são o tipo de irmãs) então eu ainda estou usando a sua resposta :)Não sei se existe uma maneira mais fácil de fazer isso sem usar uma biblioteca externa, mas eu pessoalmente amo o underscore.js, que possui vários utilitários para lidar com matrizes, coleções etc.
Com o sublinhado, você poderia fazer isso facilmente com uma linha de código:
_.pluck(arr, 'name').join(', ')
fonte
arr
é a sua matriz, naturalmente)No nó ou ES6 +:
fonte
digamos que a matriz de objetos seja referenciada pela variável
users
Se o ES6 puder ser usado, a solução mais fácil será:
Caso contrário, e o lodash pode ser usado para:
fonte
Se objeto e chaves dinâmicas:
"applications\":{\"1\":\"Element1\",\"2\":\"Element2\"}
fonte
Um tópico antigo que conheço, mas ainda super relevante para quem se deparar com isso.
Array.map foi sugerido aqui, que é um método incrível que eu uso o tempo todo. Array.reduce também foi mencionado ...
Eu pessoalmente usaria um Array.reduce para este caso de uso. Por quê? Apesar do código ser um pouco menos limpo / claro. É muito mais eficiente do que canalizar a função de mapa para uma junção.
O motivo disso é que o Array.map precisa fazer um loop sobre cada elemento para retornar uma nova matriz com todos os nomes do objeto na matriz. Array.join, em seguida, percorre o conteúdo da matriz para executar a junção.
Você pode melhorar a legibilidade do jackweirdys e reduzir a resposta usando literais de modelo para obter o código em uma única linha. "Também suportado em todos os navegadores modernos"
fonte
Não tenho certeza, mas tudo isso responde que eles funcionam, mas não são ideais, pois estão realizando duas verificações e você pode fazer isso em uma única verificação. Mesmo que O (2n) seja considerado O (n), é sempre melhor ter um O (n) verdadeiro.
Isso pode parecer uma velha escola, mas me permite fazer coisas assim:
fonte
tente isso
fonte
name
atributo. (a[i].name
Se não usar o seu de funçãoname
argumento, é equivalente aa[i]['name']
.)