Perl 6 to display an index while scrolling through a list

When looping through a list (or array), is there a way to find out the index of the current element inside the loop?

Of course, the problem can be solved by sorting the indices:

my @aa = 8 .. 12;
say "$_\t@aa[$_]" for 0 ..^ @aa.elems;

But maybe something like the following is possible (I'm marked with the .CURRENT_INDEXmethod I'm looking for)?

my @aa = 8 .. 12;
say $_.CURRENT_INDEX\t$_ for @aa;
+4
source share
3 answers

This is what really happens under the hood:

my @aa = 8 .. 12;

my \iterator = @aa.iterator;

while ($_ := iterator.pull-one) !=:= IterationEnd {
  say $_
}

The value in iteratorin this case is the anonymous class that Iterator runs .

An Iterator , . , Iterator .roll(*) , , .


, Iterator , .

my @aa = 8 .. 12;

my \iterator = class :: does Iterator {
  has $.index = 0;     # declares it as public (creates a method)
  has @.values;

  method pull-one () {
    return IterationEnd unless @!values;

    ++$!index;         # this is not needed in most uses of an Iterator
    shift @!values;
  }
}.new( values => @aa );

say "{iterator.index}\t$_" for Seq.new: iterator;
1   8
2   9
3   10
4   11
5   12

;

my @aa = 8 .. 12;

my $index = 0;
my $seq := gather for @aa { ++$index; take $_ };

say "$index\t$_" for $seq;

$_.CURRENT-INDEX , .

class Iterator-Indexer does Iterator {
  has Iterator $.iterator is required;
  has $!index = 0;

  method pull-one () {
    my \current-value = $!iterator.pull-one;

    # make sure it ends properly
    return IterationEnd if current-value =:= IterationEnd;

    # element wrapper class
    class :: {
      has $.CURRENT-INDEX;
      has $.value;

      # should have a lot more coercion methods to work properly
      method Str () { $!value }

    }.new( CURRENT-INDEX => $!index++, value => current-value )
  }
}

multi sub with-index ( Iterator \iter ){
  Seq.new: Iterator-Indexer.new: iterator => iter;
}
multi sub with-index ( Iterable \iter ){
  Seq.new: Iterator-Indexer.new: iterator => iter.iterator;
}


my @aa = 8 .. 12;
say "$_.CURRENT-INDEX()\t$_" for with-index @aa.iterator;
# note that $_ is an instance of the anonymous wrapper class

:

my @aa = 8 .. 12;

my \sequence := @aa.kv.map: -> $index, $_ {
  # note that this doesn't close over the current value in $index
  $_ but role { method CURRENT-INDEX () { $index }}
}

say "$_.CURRENT-INDEX()\t$_" for sequence;

, .pairs, , . ( .kv, for )

my @aa = 8 .. 12;
say "$_.key()\t$_.value()" for @aa.pairs;
+3

, .kv . :

my @aa = 8 .. 12;
for @aa.kv -> $i, $_ { say "$i: $_" }

0: 8
1: 9
2: 10
3: 11
4: 12
+4

Here's another way using your own index variable:

my @aa = 8..12;
say $++, ": $_" for @aa;

Conclusion:

0: 8
1: 9
2: 10
3: 11
4: 12
+1
source

Source: https://habr.com/ru/post/1687315/


All Articles