Underscore: _.chain e _.each não estão jogando juntos?

Criado em 29 dez. 2013  ·  27Comentários  ·  Fonte: jashkenas/underscore

Olá, não tenho certeza, mas acho que é um bug:

  _.chain([1,2,3,4]).each(function(current){ console.log(current) }).value(); // returns undefined
  //where: 
  _.chain([1,2,3,4]).map(function(current){ return current; }).value() // returns expected. 

Eu acho que a função encadeada tem que retornar valores, mas o toque não é iterável, estou procurando uma maneira de acessar os valores sem desencadear e sem mutação.

question

Comentários muito úteis

Existe agora um método alternativo que pode ser encadeado e permitir a modificação de elementos de uma matriz no local? Eu estava procurando por algo como peek :

_.chain(myArray)
    ...
    .peek(e -> e.craftedVar = e.otherVar * 2)
    ...
    .value();

Todos 27 comentários

Está correto. Ao contrário de map , each não tem um valor de retorno , então chamar value nele não faz nada. Se você precisar passar um array mutante pela cadeia, é melhor ficar com map .

ok então mapear, que tal _.chain (). tap (function (values) {values.forEach (function (current) {};});
não parece elegante, mas parece lógico ...

Sim, parece bom para mim:

_.chain([1,2,3,4])
 .tap(_.bind(console.log, console))
 .map(function(val) { return val * 2 })
 .value(); // [2,4,6,8]

Seria bom mencionar que cada um não retorna um valor na documentação.

@xixixao each segue a semântica de Array # forEach, que também não retorna nenhum valor. Se você precisar de algo devolvido, use um map .

Não vejo nada que impeça o sublinhado de tornar _.each encadeada. Ele rompe com a semântica nativa para outros métodos. Existem diferenças sutis em sugerir _.map já que não retorna a mesma matriz e requer um valor de retorno no retorno de chamada.

Por que cada um precisa ser encadeado? Você não está alterando o array de forma alguma (da mesma forma que está com algo como um mapa ou filtro), portanto, não há expectativas de que o valor seja reutilizável.

Por que cada um precisa ser encadeado?

Por que não permitir o encadeamento, o que poderia machucar? É útil para casos como _(collection).each(intermediateActions).filter(...) .

Eu tornaria o método indefinido em um contexto de objeto empacotado.

@ dw40 mas o que você está fazendo nessas ações intermediárias que não podem ser melhor tratadas com um mapa?

mas o que você está fazendo nessas ações intermediárias que não podem ser melhor tratadas com um mapa?

Realmente não importa qual é a etapa intermediária, pode ser uma série de coisas, a vantagem do encadeamento de _.each é que o retorno de chamada intermediário não precisa retornar um valor e não precisa crie uma nova matriz.

@ dw40 quer dar um puxão rápido? Você está falando sobre casing especial each como parte da combinação, certo?

@ akre54 Eu sei que each segue forEach , eu literalmente quis dizer que seria bom mencionar o comportamento na documentação.

Dito isso, concordo que cada um deve apenas retornar a coleção original para encadeamento (sempre, qualquer sintaxe com a qual each seja chamada).

Você está falando sobre especial-case cada como parte do mix-in certo?

Mais simples que isso. Basta ter _.each return obj . Não há necessidade de caso especial.

Mas então você está quebrando a compatibilidade com as especificações. Não é isso que each faz.

Mas então você está quebrando a compatibilidade com as especificações. Não é isso que each faz.

Eu escrevi anteriormente:

Não vejo nada que impeça o sublinhado de tornar _.cada corrente. Ele rompe com a semântica nativa para outros métodos.

Não vejo isso como grande coisa. Sublinhado já parte com o comportamento especificado para melhor usabilidade de desenvolvimento em vários métodos. Por exemplo, na borda _.keys(...) não joga se o argumento passado não for um objeto, e métodos como _.every e _.some funcionam se você não passar um iterator .

Não acho que seja uma grande mudança, mas é definitivamente inesperado que each retorne qualquer coisa, muito menos o valor que foi passado (e uma quebra de especificação muito maior do que a verificação de argumentos nulos).

Para ser claro, você está falando sobre fazer essa mudança, certo?

diff --git a/underscore.js b/underscore.js
index 7a30b0a..2b56536 100644
--- a/underscore.js
+++ b/underscore.js
@@ -74,7 +74,7 @@
   // Handles objects with the built-in `forEach`, arrays, and raw objects.
   // Delegates to **ECMAScript 5**'s native `forEach` if available.
   var each = _.each = _.forEach = function(obj, iterator, context) {
-    if (obj == null) return;
+    if (obj == null) return obj;
     if (nativeForEach && obj.forEach === nativeForEach) {
       obj.forEach(iterator, context);
     } else if (obj.length === +obj.length) {
@@ -87,6 +87,7 @@
         if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
       }
     }
+    return obj;
   };

Para ser claro, você está falando sobre fazer essa mudança, certo?

Direito.

Eu não me importo particularmente de uma forma ou de outra, mas seria bom ouvir mais pessoas sobre casos de uso reais a favor ou contra isso antes da fusão.

Eu acho que você pode ir em frente. Seria um pouco mais útil.

Na minha opinião, pelo menos ao trabalhar em um contexto encadeado, fazer _.cada retorno um valor é o comportamento esperado, então +1 :)

@LeonFedotov @ dw40 tente.

@ akre54 Incrível.

@ akre54 ótimo, obrigado!

Curiosamente, voltamos ao comportamento pré-1.1.3.

A seguinte adição às notas da versão 1.1.3 foi feita em 3b916a2cf788a4588f08323c39786b6fb5ddbca6:

_.each não retorna mais a coleção iterada, para maior consistência com forEach do ECMA5.

Ha. Eu sabia que parecia familiar. Bom lugar.
Em 1 de fevereiro de 2014 23h23, "David Chambers" [email protected] escreveu:

Curiosamente, voltamos ao comportamento pré-1.1.3.

A seguinte adição às notas da versão 1.1.3 foi feita em 3b916a2 https://github.com/jashkenas/underscore/commit/3b916a2cf788a4588f08323c39786b6fb5ddbca6
:

_.each não retorna mais a coleção iterada, para melhor
consistência com forEach do ECMA5.

Responda a este e-mail diretamente ou visualize-o em Gi tHubhttps: //github.com/jashkenas/underscore/issues/1391#issuecomment -33883825
.

Existe agora um método alternativo que pode ser encadeado e permitir a modificação de elementos de uma matriz no local? Eu estava procurando por algo como peek :

_.chain(myArray)
    ...
    .peek(e -> e.craftedVar = e.otherVar * 2)
    ...
    .value();
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

jdalton picture jdalton  ·  6Comentários

jezen picture jezen  ·  8Comentários

marcalj picture marcalj  ·  5Comentários

zackschuster picture zackschuster  ·  5Comentários

afranioce picture afranioce  ·  8Comentários