Underscore: _.chain & _.each no están jugando juntos?

Creado en 29 dic. 2013  ·  27Comentarios  ·  Fuente: jashkenas/underscore

Hola, no estoy seguro, pero creo que esto es un error:

  _.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. 

Supongo que la función encadenada tiene que devolver valores, pero luego el tap no es iterable, estoy buscando una forma de acceder a los valores sin desencadenarlos y sin mutación.

question

Comentario más útil

¿Existe ahora un método alternativo que se pueda encadenar y permitir la modificación de elementos de una matriz en su lugar? Estaba buscando algo como peek :

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

Todos 27 comentarios

Eso es correcto. A diferencia de map , each no tiene un valor de retorno , por lo que llamar a value no hace nada. Si necesita pasar una matriz mutada a través de la cadena, es mejor quedarse con map .

ok entonces mapa, ¿qué tal _.chain (). tap (función (valores) {valores.paraCada (función (actual) {};});
no parece elegante pero parece lógico ...

Sí, me queda bien :

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

Sería bueno mencionar que cada uno no devuelve un valor en la documentación.

@xixixao each sigue la semántica de Array # forEach, que tampoco devuelve ningún valor. Si necesita que le devuelvan algo, simplemente use map .

No veo nada que impida que Underscore haga _.each encadenable. Rompe con la semántica nativa por otros métodos. Existen diferencias sutiles al sugerir _.map como si no devolviera la misma matriz y requiriera un valor de retorno en la devolución de llamada.

¿Por qué cada uno debería ser encadenable? No está mutando la matriz de ninguna manera (como lo hace con algo como un mapa o un filtro), por lo que no hay expectativas de que el valor sea reutilizable.

¿Por qué cada uno debería ser encadenable?

¿Por qué no permitir el encadenamiento, qué podría doler? Es útil para casos como _(collection).each(intermediateActions).filter(...) .

Haría el método indefinido en un contexto de objeto envuelto.

@ dw40 pero ¿qué estás haciendo en esas acciones intermedias que no se pueden manejar mejor con un mapa?

pero ¿qué estás haciendo en esas acciones intermedias que no se pueden manejar mejor con un mapa?

Realmente no importa cuál sea el paso intermedio, podría ser una serie de cosas, el beneficio del encadenamiento _.each es que la devolución de llamada intermedia no tiene que devolver un valor y no es necesario crea una nueva matriz.

@ dw40 ¿ quieres preparar un tirón rápido? Estás hablando de carcasas especiales each como parte de la mezcla, ¿verdad?

@ akre54 Sé que each sigue a forEach , literalmente quise decir que sería bueno mencionar el comportamiento en la documentación.

Dicho esto, estoy de acuerdo en que cada uno debería devolver la colección original para encadenar (siempre, cualquier sintaxis con la que se llame each ).

Estás hablando de carcasas especiales para cada uno como parte de la mezcla, ¿verdad?

Más simple que eso. Solo haz que _.each devuelva obj . No es necesario un caso especial.

Pero luego estás rompiendo la compatibilidad con las especificaciones. Eso no es lo que hace each .

Pero luego estás rompiendo la compatibilidad con las especificaciones. Eso no es lo que hace each .

Anteriormente escribí:

No veo nada que impida que Underscore haga _.each encadenable. Rompe con la semántica nativa por otros métodos.

No veo eso como un gran problema. Subraye las partes que ya tienen el comportamiento especificado para una mejor usabilidad del desarrollador en varios métodos. Por ejemplo, en edge _.keys(...) no arroja si el argumento pasado no es un objeto, y métodos como _.every y _.some funcionan si no pasa un iterator .

No creo que sea un gran cambio, pero definitivamente es inesperado que each devuelva algo, y mucho menos el valor que se le pasó (y una ruptura de especificación mucho mayor que la verificación de argumentos nulos).

Para ser claros, estás hablando de hacer este cambio, ¿verdad?

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 claros, estás hablando de hacer este cambio, ¿verdad?

Correcto.

No me importa particularmente de una forma u otra, pero sería bueno escuchar a más personas sobre casos de uso reales a favor o en contra de esto antes de fusionar.

Creo que puedes hacerlo. Sería un poco más útil.

En mi opinión, al menos cuando se trabaja en un contexto encadenado, hacer que _.each devuelva un valor es un comportamiento esperado, por lo que +1 :)

@LeonFedotov @ dw40 pruébalo.

@ akre54 Impresionante.

@ akre54 genial, ¡gracias!

Curiosamente, hemos vuelto al comportamiento anterior a 1.1.3.

La siguiente adición a las notas de la versión 1.1.3 se realizó en 3b916a2cf788a4588f08323c39786b6fb5ddbca6:

_.each ya no devuelve la colección iterada, para mejorar la coherencia con forEach ECMA5.

Decir ah. Sabía que me parecía familiar. Buen lugar.
El 1 de febrero de 2014 a las 11:23 p.m., "David Chambers" [email protected] escribió:

Curiosamente, hemos vuelto al comportamiento anterior a 1.1.3.

La siguiente adición a las notas de la versión 1.1.3 se realizó en 3b916a2 https://github.com/jashkenas/underscore/commit/3b916a2cf788a4588f08323c39786b6fb5ddbca6
:

_.each ya no devuelve la colección iterada, para mejorar
coherencia con ECMA5's forEach.

Responda a este correo electrónico directamente o véalo en Gi
.

¿Existe ahora un método alternativo que se pueda encadenar y permitir la modificación de elementos de una matriz en su lugar? Estaba buscando algo como peek :

_.chain(myArray)
    ...
    .peek(e -> e.craftedVar = e.otherVar * 2)
    ...
    .value();
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

clouddueling picture clouddueling  ·  3Comentarios

zackschuster picture zackschuster  ·  5Comentarios

markvr picture markvr  ·  3Comentarios

chikamichi picture chikamichi  ·  8Comentarios

jdalton picture jdalton  ·  4Comentarios