39 votes

Est-ce que "map" est une boucle?

En répondant à cette question, je me rends compte que je n'étais pas sûr de savoir si Perl map peut être considéré comme une boucle ou pas?

D'une part, il charlatans/marche comme une boucle (ne O(n), peut être facilement ré-écrit par un équivalent de la boucle, et une sorte de correspond à la définition commune = "une séquence d'instructions qui est continuellement répété").

D'autre part, map n'est généralement pas répertoriés parmi Perl structures de contrôle, dont les boucles sont un sous-ensemble de. E. g. http://en.wikipedia.org/wiki/Perl_control_structures#Loops

Donc, ce que je suis à la recherche d'une raison formelle d'être convaincu d'un côté contre l'autre. Jusqu'à présent, l'ancien (c'est une boucle) des sons beaucoup plus convaincant pour moi, mais je suis gêné par le fait que je n'ai jamais vu "carte" mentionné dans une liste de Perl boucles.

30voto

Carson Myers Points 11135

la carte est d'un niveau plus élevé concept de boucles, emprunté à la programmation fonctionnelle. Il ne dit pas "appeler cette fonction sur chacun de ces éléments, un par un, du début à la fin," dit-il "l'appel de cette fonction sur l'ensemble de ces éléments." Il pourrait être mis en œuvre comme une boucle, mais ce n'est pas le point -- il peut également être mis en œuvre de manière asynchrone -- il en serait toujours à la carte.

En outre, il n'est pas vraiment une structure de contrôle en lui-même-ce que si chaque fonction perl qui ont utilisé une boucle dans sa mise en œuvre ont été inscrites en vertu de la "boucle?" Juste parce que quelque chose est mis en œuvre à l'aide d'une boucle, ne signifie pas qu'il doit être considéré comme son propre type de boucle.

26voto

pilcrow Points 20628

Non, ce n'est pas une boucle, de mon point de vue.

La caractéristique des boucles (perl) est qu'elles peuvent être divisées en ( last ) ou reprises ( next , redo ). map ne peut pas:

 map { last } qw(stack overflow);  # ERROR!  Can't "last" outside a loop block
 

Le message d'erreur suggère que Perl lui-même ne considère pas le bloc évalué comme un bloc de boucle .

19voto

Eric Strom Points 30894

Du point de vue académique, un cas peut être faite pour les deux, selon la façon dont la carte est défini. Si elle a toujours itère dans l'ordre, puis un foreach boucle peut être émulé par l' map ce qui rend les deux équivalent. Certaines autres définitions de la carte peut permettre de sortir de l'exécution de l'ordre de la liste pour la performance (la division du travail entre les threads ou même des ordinateurs distincts). La même chose pourrait être fait avec l' foreach construire.

Mais aussi loin que Perl 5, map est toujours exécuté dans l'ordre, ce qui équivaut à une boucle. La structure interne de l'expression map $_*2, 1, 2, 3 les résultats dans la suite de l'exécution de l'ordre opcodes qui montrent que l' map est intégré en interne en tant que while-comme la structure de contrôle:

OP  enter
COP nextstate
OP  pushmark
SVOP const IV 1
SVOP const IV 2
SVOP const IV 3
LISTOP mapstart
LOGOP (0x2f96150) mapwhile  <-- while still has items, shift one off into $_
    PADOP gvsv GV *_            
    SVOP const IV 2             loop body
    BINOP multiply              
    goto LOGOP (0x2f96150)  <-- jump back to the top of the loop
LISTOP leave 

12voto

Chas. Owens Points 40887

L' map fonction n'est pas une boucle en Perl. Cela peut être vu clairement par l'échec de l' next, redo, et last à l'intérieur d'un map:

perl -le '@a = map { next if $_ %2; } 1 .. 5; print for @a'
Can't "next" outside a loop block at -e line 1.

Pour atteindre l'effet souhaité en map, vous devez renvoyer une liste vide:

perl -le '@a = map { $_ %2 ? () : $_ } 1 .. 5; print for @a'
2
4

Je pense que la transformation est meilleur nom pour des constructions comme map. Il transforme une liste dans une autre. Une fonction similaire à l' map est List::Util::reduce, mais au lieu de transformer une liste dans une autre liste, il transforme une liste en une valeur scalaire. En utilisant le mot de transformation, nous pouvons parler des aspects communs de ces deux fonctions supérieures.

Cela dit, il fonctionne en visitant tous les membres de la liste. Cela signifie qu'il se comporte un peu comme une boucle, et selon ce que votre définition de la "boucle" est-ce que l'on pourrait qualifier. Remarque, ma définition signifie qu'il n'y a pas de boucle dans le présent code, soit:

#!/usr/bin/perl

use strict;
use warnings;

my $i = 0;
FOO:
    print "hello world!\n";
goto FOO unless ++$i == 5;

Perl en fait de définir le mot de boucle dans sa documentation:

   loop
       A construct that performs something repeatedly, like a roller
       coaster.

Par cette définition, map est une boucle car il préformes son bloc à plusieurs reprises; toutefois, il définit également des "boucle de contrôle de l'instruction" et "boucle label":

   loop control statement
       Any statement within the body of a loop that can make a loop
       prematurely stop looping or skip an "iteration".  Generally you
       shouldn't try this on roller coasters.

   loop label
       A kind of key or name attached to a loop (or roller coaster) so
       that loop control statements can talk about which loop they want to
       control.

Je crois qu'il est imprécis à l'appel map une boucle car next et ses comparses sont définis de la boucle de contrôle des déclarations et ils ne peuvent pas contrôler map.

C'est tout simplement de jouer avec les mots mais. Décrivant map comme-une-boucle est un bon moyen de présenter quelqu'un à elle. Même la documentation pour map utilise un foreach boucle dans le cadre de son exemple:

               %hash = map { get_a_key_for($_) => $_ } @array;

           is just a funny way to write

               %hash = ();
               foreach (@array) {
                   $hash{get_a_key_for($_)} = $_;
               }

Tout dépend du contexte, si. Il est utile de décrire la multiplication à quelqu'un, comme on le répète outre, lorsque vous essayez de passer par lui pour comprendre le concept, mais vous ne voulez pas de continuer à penser de cette façon. Vous voulez lui apprendre les règles de la multiplication au lieu de toujours traduire retour aux règles de l'addition.

11voto

FMc Points 22663

Votre question tourne sur la question de la classification. Au moins, en vertu d'une interprétation, en se demandant si map est une boucle, c'est comme demander si map est un sous-ensemble de la "Boucle". Encadrée de cette façon, je pense que la réponse est non. Bien qu' map et Boucle avons beaucoup de choses en commun, il y a des différences importantes.

  • Commandes de boucle: Chas. Owens fait un dossier solide que Perl boucles sont soumis à des commandes de boucle comme next et last, tandis que l' map ne l'est pas.
  • Les valeurs de retour: le but de l' map est sa valeur de retour; avec des boucles, pas tellement.

Nous rencontrons des relations comme ça tout le temps dans le monde réel, des choses qui ont beaucoup en commun les uns avec les autres, mais aucune n'étant parfait sous-ensemble de l'autre.

 -----------------------------------------
|Things that iterate?                     |
|                                         |
|      ------------------                 |
|     |map()             |                |
|     |                  |                |
|     |          --------|----------      |
|     |          |       |          |     |
|     |          |       |          |     |
|      ------------------           |     |
|                |                  |     |
|                |              Loop|     |
|                 ------------------      |
|                                         |
 -----------------------------------------

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X