Underscore: _.chain et _. chacun ne joue pas ensemble?

Créé le 29 déc. 2013  ·  27Commentaires  ·  Source: jashkenas/underscore

Salut je ne suis pas sûr mais je pense que c'est un 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. 

Je suppose que la fonction chaînée doit renvoyer des valeurs, mais alors tap n'est pas une itération, je cherche un moyen d'accéder aux valeurs sans les désenchaîner et sans mutation.

question

Commentaire le plus utile

Existe-t-il maintenant une méthode alternative qui peut être chaînée et permettre de modifier les éléments d'un tableau en place? Je cherchais quelque chose comme un peek :

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

Tous les 27 commentaires

C'est correct. Contrairement à map , each n'a pas de valeur de retour , donc appeler value dessus ne fait rien. Si vous devez passer un tableau muté à travers la chaîne, il est préférable de vous en tenir à map .

ok alors map, que diriez-vous de _.chain (). tap (function (values) {values.forEach (function (current) {};});
ne semble pas élégant mais semble logique ...

Oui, ça me

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

Il serait bon de mentionner que chacun ne renvoie pas de valeur dans la documentation.

@xixixao each suit la sémantique de Array # forEach, qui ne renvoie pas non plus de valeur. Si vous avez besoin de quelque chose de retourné, utilisez simplement un map .

Je ne vois rien qui empêche Underscore de rendre _.each chaînable. Il rompt avec la sémantique native des autres méthodes. Il y a des différences subtiles avec la suggestion de _.map comme si elle ne renvoie pas le même tableau et qu'elle nécessite une valeur de retour dans le rappel.

Pourquoi chacun devrait-il être chaînable? Vous ne mute en aucune façon le tableau (comme vous le faites avec quelque chose comme une carte ou un filtre), donc il n'y a aucune attente de la valeur réutilisable.

Pourquoi chacun devrait-il être chaînable?

Pourquoi ne pas autoriser le chaînage, qu'est-ce que ça pourrait faire de mal? C'est pratique pour des cas comme _(collection).each(intermediateActions).filter(...) .

Je rendrais la méthode indéfinie dans un contexte d'objet enveloppé.

@ dw40 mais que faites-vous dans ces actions intermédiaires qui ne peuvent pas être mieux gérées avec une carte?

mais que faites-vous dans ces actions intermédiaires qui ne peuvent pas être mieux gérées avec une carte?

L'étape intermédiaire n'a pas vraiment d'importance, cela peut être un certain nombre de choses, l'avantage du chaînage _.each est que le rappel intermédiaire n'a pas à renvoyer une valeur et il n'a pas besoin de créer un nouveau tableau.

@ dw40 voulez fouetter un coup rapide? Vous parlez d'un boîtier spécial each dans le cadre du mix-in, n'est-ce pas?

@ akre54 Je sais que each suit forEach , je voulais littéralement dire qu'il serait bon de mentionner le comportement dans la documentation.

Cela dit, je suis d'accord que chacun devrait simplement renvoyer la collection originale pour le chaînage (toujours, quelle que soit la syntaxe avec laquelle each est appelée).

Vous parlez de boîtiers spéciaux chacun dans le cadre du mix-in, n'est-ce pas?

Plus simple que ça. Il suffit d'avoir _.each return obj . Pas besoin de cas particulier.

Mais alors vous rompez la compatibilité avec les spécifications. Ce n'est pas ce que fait each .

Mais alors vous rompez la compatibilité avec les spécifications. Ce n'est pas ce que fait each .

J'ai écrit précédemment:

Je ne vois rien qui empêche Underscore de rendre _.each chaînable. Il rompt avec la sémantique native des autres méthodes.

Je ne vois pas cela comme un problème. Soulignez les parties déjà avec le comportement spécifié pour une meilleure utilisabilité de développement dans plusieurs méthodes. Par exemple dans edge _.keys(...) ne lance pas si l'argument passé n'est pas un objet, et des méthodes comme _.every et _.some fonctionnent si vous ne passez pas un iterator .

Je ne pense pas que ce soit un changement énorme, mais il est certainement inattendu que each retournera quoi que ce soit, sans parler de la valeur qui a été passée (et une rupture de spécification beaucoup plus importante que la vérification des arguments nuls).

Pour être clair, vous parlez de faire ce changement, non?

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;
   };

Pour être clair, vous parlez de faire ce changement, non?

Droite.

Je ne me soucie pas particulièrement d'une manière ou d'une autre, mais il serait bon d'entendre plus de gens parler de cas d'utilisation réels pour ou contre cela avant de fusionner.

Je pense que tu peux y aller. Serait un peu plus utile.

À mon avis, au moins lorsque vous travaillez dans un contexte chaîné, faire de _.each renvoyer une valeur est un comportement attendu, donc +1 :)

@LeonFedotov @ dw40 essayez cela.

@ akre54 Génial.

@ akre54 super, merci!

Fait intéressant, nous sommes revenus au comportement pré-1.1.3.

L'ajout suivant aux notes de publication de la version 1.1.3 a été fait dans 3b916a2cf788a4588f08323c39786b6fb5ddbca6:

_.each ne renvoie plus la collection itérée, pour une meilleure cohérence avec forEach d'ECMA5.

Ha. Je savais que cela me semblait familier. Bon endroit.
Le 1er février 2014 à 23 h 23, "David Chambers" [email protected] a écrit:

Fait intéressant, nous sommes revenus au comportement pré-1.1.3.

L'ajout suivant aux notes de publication de la version 1.1.3 a été effectué dans 3b916a2 https://github.com/jashkenas/underscore/commit/3b916a2cf788a4588f08323c39786b6fb5ddbca6
:

_.each ne renvoie plus la collection itérée, pour une amélioration
cohérence avec forEach de l'ECMA5.

Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps: //github.com/jashkenas/underscore/issues/1391#issuecomment -33883825
.

Existe-t-il maintenant une méthode alternative qui peut être chaînée et permettre de modifier les éléments d'un tableau en place? Je cherchais quelque chose comme un peek :

_.chain(myArray)
    ...
    .peek(e -> e.craftedVar = e.otherVar * 2)
    ...
    .value();
Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

acl0056 picture acl0056  ·  5Commentaires

xiaoliwang picture xiaoliwang  ·  3Commentaires

danilopolani picture danilopolani  ·  5Commentaires

jdalton picture jdalton  ·  4Commentaires

ksullivan picture ksullivan  ·  9Commentaires