Iterators: Difference between revisions

10,584 bytes added ,  5 months ago
m
→‎{{header|Wren}}: Changed to Wren S/H
(added Perl programming solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(5 intermediate revisions by 5 users not shown)
Line 118:
dc.b "Purple",0
even</syntaxhighlight>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="AutoHotkey">oDays := ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]
oColors := ["Red","Orange","Yellow","Green","Blue","Purple"]
MsgBox % Result := ""
. "All elements:`n" Iterators(oDays) "`n" Iterators(oColors)
. "`n`nFirst, fourth, and fifth:`n" Iterators(oDays, [1,4,5]) "`n" Iterators(oColors, [1,4,5])
. "`n`nReverse first, fourth, and fifth:`n" Iterators(oDays, [1,4,5], 1) "`n" Iterators(oColors, [1,4,5], 1)
return
 
Iterators(obj, num:="", rev:=0){
for i, v in (num.Count() ? num : obj)
res .= (rev ? obj[obj.Count() +1 -v] : num.Count() ? obj[v] : v) ", "
return Trim(res, ", ") "."
}</syntaxhighlight>
{{out}}
<pre>All elements:
Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday.
Red, Orange, Yellow, Green, Blue, Purple.
 
First, fourth, and fifth:
Sunday, Wednesday, Thursday.
Red, Green, Blue.
 
Reverse first, fourth, and fifth:
Saturday, Wednesday, Tuesday.
Purple, Yellow, Orange.</pre>
 
=={{header|BASIC256}}==
Line 220 ⟶ 247:
Purple, Yellow, Orange
</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|Classes,StdCtrls,ExtCtrls}}
This uses a simiple iterator built from Delphi objects. Like all iterators, it hides the detail of how the collection of items is stored. The user can only access the data by called methods such as "Next" and "Previous." The object could be made generic so any type of collection object could be used to create a custom iterator.
 
<syntaxhighlight lang="Delphi">
{Simple iterator based around a string collection}
{The details of string storage are hidden from the user}
{Strings are only accessible through the supplied interface}
 
type TStringIterator = class(TObject)
private
Collection: TStringList;
Index: integer;
protected
public
constructor Create;
destructor Destroy; override;
procedure Add(S: string);
procedure Insert(const Item, Before: string);
procedure Remove(const Item: string);
procedure Clear;
function Contains(const Item: string): Boolean;
function GetCount: Integer;
procedure Reset;
function Next: Boolean;
function Previous: Boolean;
procedure Last;
function CurrentItem: string;
procedure LoadArray(SA: array of string);
end;
 
{ TStringIterator }
 
procedure TStringIterator.Add(S: string);
{Add item to Collection}
begin
Collection.Add(S);
end;
 
procedure TStringIterator.Clear;
{Clear collection}
begin
Collection.Clear;
end;
 
function TStringIterator.Contains(const Item: string): Boolean;
{Test if string is in collection}
begin
Result:=Collection.IndexOf(Item)>=0;
end;
 
constructor TStringIterator.Create;
{Create collection and initialize}
begin
Collection:=TStringList.Create;
Clear;
Reset;
end;
 
 
function TStringIterator.CurrentItem: string;
{Return current item from collection}
begin
Result:=Collection[Index];
end;
 
destructor TStringIterator.Destroy;
{Dispose of collection}
begin
Collection.Free;
inherited;
end;
 
 
function TStringIterator.GetCount: Integer;
{Return count of items in collection}
begin
Result:=Collection.Count;
end;
 
procedure TStringIterator.Insert(const Item, Before: string);
{Insert item in collection before specified item}
{If "Before" isn't found, insert at end of collection}
var Inx: integer;
begin
if Before='' then Collection.Add(Item)
else
begin
Inx:=Collection.IndexOf(Before);
if Inx>=0 then Collection.Insert(Inx,Item);
end
end;
 
function TStringIterator.Next: Boolean;
{Point to next item in collection}
{Return false if no more items in collection}
begin
Result:=(Index<Collection.Count-1);
if Result then Inc(Index);
end;
 
function TStringIterator.Previous: Boolean;
{Point to previous item in collection}
{Return false if no more Previous items in collection}
begin
Result:=(GetCount>0) and (Index>0);
if Result then Dec(Index);
end;
 
 
procedure TStringIterator.Remove(const Item: string);
{Remove specified item from list}
var Inx: integer;
begin
Inx:=Collection.IndexOf(Item);
if Inx>=0 then Collection.Delete(Inx);
end;
 
procedure TStringIterator.Reset;
{Point to start of collection}
begin
Index:=0;
end;
 
procedure TStringIterator.Last;
{Point to Last item in collection}
begin
Index:=Collection.Count-1;
end;
 
 
 
procedure TStringIterator.LoadArray(SA: array of string);
{Load array of strings into Collection}
var I: integer;
begin
for I:=0 to High(SA) do Add(SA[I]);
end;
 
 
{-----------------------------------------------------------}
 
 
procedure TestIterator(Memo: TMemo);
var WeekDays,Colors: TStringIterator;
 
function Traverse(Iter: TStringIterator): string;
begin
Iter.Reset;
Result:='';
repeat Result:=Result+Iter.CurrentItem+' ';
until not Iter.Next;
end;
 
function FirstFourthFifth(Iter: TStringIterator): string;
var I: integer;
begin
Iter.Reset;
Result:='';
Result:=Result+Iter.CurrentItem+' ';
for I:=1 to 3 do Iter.Next;
Result:=Result+Iter.CurrentItem+' ';
Iter.Next;
Result:=Result+Iter.CurrentItem+' ';
end;
 
function LastFourthFifth(Iter: TStringIterator): string;
var I: integer;
begin
Iter.Last;
Result:='';
Result:=Result+Iter.CurrentItem+' ';
for I:=1 to 3 do Iter.Previous;
Result:=Result+Iter.CurrentItem+' ';
Iter.Previous;
Result:=Result+Iter.CurrentItem+' ';
end;
 
begin
WeekDays:=TStringIterator.Create;
try
Colors:=TStringIterator.Create;
try
WeekDays.LoadArray(['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']);
Colors.LoadArray(['Red','Orange','Yellow','Green','Blue','Purple']);
 
Memo.Lines.Add(Traverse(Weekdays));
Memo.Lines.Add(Traverse(Colors));
Memo.Lines.Add(FirstFourthFifth(Weekdays));
Memo.Lines.Add(FirstFourthFifth(Colors));
Memo.Lines.Add(LastFourthFifth(Weekdays));
Memo.Lines.Add(LastFourthFifth(Colors));
 
finally Colors.Free; end;
finally WeekDays.Free; end;
end;
 
</syntaxhighlight>
{{out}}
<pre>
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Red Orange Yellow Green Blue Purple
Sunday Wednesday Thursday
Red Green Blue
Saturday Wednesday Tuesday
Purple Yellow Orange
 
</pre>
 
 
 
Line 434 ⟶ 672:
 
(Except that this approach does not support negative indexing, so indexing from the end of a list would, for the general case, require either extending the system with explicit support for a length operation or iterating once over the list to determine the list length.)
 
=={{header|jq}}==
'''Works with both jq and gojq, the C and Go implementations of jq'''
 
In this entry, singly-linked lists (SLL) are represented
by JSON objects of the form `{item, next}`, that is by
objects with two keys, where `.item` is an item in
the list, and `.next` is the next SLL.
 
Since jq does not have an iterator interface, and since jq's array iterator is not extensible,
this entry defines a collection of polymorphic functions that will accept arrays or SLLs
as input, and that will produce identical results for equivalent inputs.
To highlight these functions, they will be named by using the prefix "poly_".
 
In particular, the function `poly_task` illustrates how all the
specified tasks for this page can be defined without reference to the input type,
with the results being the
same for equivalent inputs.
<syntaxhighlight lang=jq>
# Generic utilities
def count(s): reduce s as $x (0; .+1);
 
# A constructor for SLL:
def new($item): {$item, next: null};
 
# Append a single item to an array or SLL.
# If the input is {} or a SLL, the output is a SLL
# If the input is null or an array, the output is an array
def append($item):
def a: if .next then .next |= a else .next=new($item) end;
if . == null then [$item]
elif . == {} then new($item)
else a
end;
 
# Append a stream of items using `append/1`
def append_items(stream):
reduce stream as $item (.; append($item));
 
# Produce a stream of items
def poly_items:
if type == "array" then .[]
else .item, (select(.next).next|poly_items)
end;
 
def poly_length:
if type == "array" then length
else count(poly_items)
end;
 
# Output: the stream of items in reversed order
def poly_reversed:
if type == "array" then .[range(length-1; -1; -1)]
else [poly_items] | reverse[]
end;
 
# Two representations of Days of the Week (dow) and of colors:
def dow: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
def sll_dow: {} | append_items(dow[]);
 
def colors: [ "red", "orange", "yellow", "green", "blue", "indigo", "violet"];
def sll_colors: {} | append_items(colors[]);
 
def poly_task:
poly_length as $length
| "All the elements:", poly_items,
"",
"The first, fourth, and fifth elements:",
((0, 3, 4) as $i
| "For i=\($i): \(nth($i; poly_items))" ),
"",
"The last, fourth to last, and fifth to last elements:",
((0, 3, 4) as $i
| "For i=\($i): \(nth($i; poly_reversed) )" );
 
 
"For days of the week:",
"For arrays:", (dow | poly_task),
"",
"For singly-linked lists:", (sll_dow | poly_task),
"\n",
"For colors:",
"For arrays:", (colors | poly_task),
"",
"For singly-linked lists:", (sll_colors | poly_task)
</syntaxhighlight>
{{output}}
<pre style="height:20lh;overflow:auto>
For days of the week:
For arrays:
All the elements:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
 
The first, fourth, and fifth elements:
For i=0: Monday
For i=3: Thursday
For i=4: Friday
 
The last, fourth to last, and fifth to last elements:
For i=0: Sunday
For i=3: Thursday
For i=4: Wednesday
 
For singly-linked lists:
All the elements:
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
 
The first, fourth, and fifth elements:
For i=0: Monday
For i=3: Thursday
For i=4: Friday
 
The last, fourth to last, and fifth to last elements:
For i=0: Sunday
For i=3: Thursday
For i=4: Wednesday
 
 
For colors:
For arrays:
All the elements:
red
orange
yellow
green
blue
indigo
violet
 
The first, fourth, and fifth elements:
For i=0: red
For i=3: green
For i=4: blue
 
The last, fourth to last, and fifth to last elements:
For i=0: violet
For i=3: green
For i=4: yellow
 
For singly-linked lists:
All the elements:
red
orange
yellow
green
blue
indigo
violet
 
The first, fourth, and fifth elements:
For i=0: red
For i=3: green
For i=4: blue
 
The last, fourth to last, and fifth to last elements:
For i=0: violet
For i=3: green
For i=4: yellow
</pre>
 
 
=={{header|Julia}}==
Line 488 ⟶ 898:
</pre>
 
=={{header|PerlNim}}==
Nim defines iterators for collection types such as arrays, sequences, sets, tables, etc. But it allows also to define our own iterators. There exists two kinds of such iterators: inline iterators (the current default) and closure iterators. Inline iterators are expanded, closure iterators are not.
<syntaxhighlight lang="perl" line># 20221013 Perl programming solution
 
In our solution, we use standard iterators and our own iterators.
use strict;
<syntaxhighlight lang="Nim">import std/lists
use warnings;
 
# Days stored in an array.
sub printArrayForward ($@) {
let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
my ($aref,@needles) = @_;
my $pointer = 0;
while ( defined ( my $needle = shift @needles )) {
while ( $needle > $pointer and defined $aref->[$pointer] ) { ++$pointer }
print "$aref->[$pointer++] " if $pointer == $needle;
}
}
 
# Colors stored in a doubly linked list.
sub printArrayBackward ($@) {
let colors = ["Red", "Orange", "Yellow", "Green", "Blue", "Purple"].toDoublyLinkedList
my ($aref,@needles) = @_ ;
my ($pointer, $end) = (0, -1);
while ( defined $aref->[++$pointer] ) { };
while ( defined ( my $needle = shift @needles )) {
while ( $needle < $end ) { --$end and --$pointer }
print "$aref->[$pointer-1] " if $end == $needle;
last unless defined $aref->[$pointer-1]
}
}
 
sub printLListForward ($@) {
my ($llref,@needles) = @_;
my $pointer = 0;
while ( defined ( my $needle = shift @needles )) {
while ( $needle > $pointer and defined $llref->[1] ) {
++$pointer and $llref = $llref->[1]
}
print "$llref->[0] " if $pointer == $needle;
++$pointer and $llref = $llref->[1];
}
}
 
### To print the elements of "days", we use a standard iterator.
sub printLListBackward ($@) {
echo "Content of “days” array:"
my ($llref,@needles) = @_;
for day in days:
my ($end, @stack) = -1;
echo day
while ( defined $llref->[1] ) {
echo()
unshift @stack, $llref->[0] and $llref = $llref->[1]
}
while ( defined ( my $needle = shift @needles )) {
while ( $needle < $end ) { --$end and shift @stack }
print shift @stack , " " and --$end
}
}
 
my @dow = qw <Sunday Monday Tuesday Wednesday Thursday Friday Saturday>;
my @color = qw <red orange yellow green blue purple>;
 
### To print the elements of "colors", we use a standard iterator.
my $LList = [ undef ];
echo "Content of “colors” list:"
foreach ( reverse @color ) { $LList = [ $_ , $LList ] }
for color in colors:
my $copy = $LList;
echo color
echo()
 
print "All elements:\n";
for ( @dow ) { print "$_ " }
print "\n";
while ( defined $copy->[1] ) { print "$copy->[0] " and $copy = $copy->[1] }
 
### To print "\n\nFirstthe first, fourth, andan fifth elements:\n";
### of "days", we use a standard iterator.
printArrayForward \@dow, (0,3,4);
echo "First, fourth and fifth elements of “days”:"
print "\n";
for i, day in days:
printLListForward $LList, (0,3,4);
if i + 1 in [1, 4, 5]:
echo day
echo()
 
print "\n\nReverse first, fourth, and fifth elements:\n";
printArrayBackward \@dow, (-1,-4,-5);
print "\n";
printLListBackward $LList, (-1,-4,-5);
print "\n";</syntaxhighlight>{{out}}
<pre>All elements:
Sunday Monday Tuesday Wednesday Thursday Friday Saturday
red orange yellow green blue purple
 
First### To print the first, fourth, andan fifth elements:
### of "colors", we must define our own iterator.
Sunday Wednesday Thursday
red green blue
 
iterator enumerate[T](list: DoublyLinkedList[T]): (int, T) =
Reverse first, fourth, and fifth elements:
## Yield the successive (index, value).*
Saturday Wednesday Tuesday
## First index is 0.
purple yellow orange
var i = 0
var node = list.head
while node != nil:
yield (i, node.value)
node = node.next
inc i
 
echo "First, fourth and fifth elements of “colors”:"
for i, color in colors.enumerate:
if i + 1 in [1, 4, 5]:
echo color
echo()
 
 
### To print the last, fourth to last, and fifth to last
### elements of "days", we must define our own iterator.
 
iterator revItems[T](a: openArray[T]): (int, T) =
## Starting from end of array, yield (index, value).
## First index is 1.
for i in countdown(a.high, 0):
yield (a.len - i, a[i])
 
echo "Last, fourth to last and fifth to last elements of “days”:"
for i, day in days.revItems:
if i in [1, 4, 5]:
echo day
echo()
 
 
### To print the last, fourth to last, and fifth to last
### elements of "colors", we must define our own iterator.
 
iterator revItems[T](list: DoublyLinkedList[T]): (int, T) =
## Starting from end of the list, yield (index, value).
## First index is 1.
var i = 1
var node = list.tail
while node != nil:
yield (i, node.value)
node = node.prev
inc i
 
echo "Last, fourth to last and fifth to last elements of “colors”:"
for i, color in colors.revItems:
if i in [1, 4, 5]:
echo color
</syntaxhighlight>
 
{{out}}
<pre>Content of “days” array:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
 
Content of “colors” list:
Red
Orange
Yellow
Green
Blue
Purple
 
First, fourth and fifth elements of “days”:
Sunday
Wednesday
Thursday
 
First, fourth and fifth elements of “colors”:
Red
Green
Blue
 
Last, fourth to last and fifth to last elements of “days”:
Saturday
Wednesday
Tuesday
 
Last, fourth to last and fifth to last elements of “colors”:
Purple
Yellow
Orange
</pre>
 
Line 911 ⟶ 1,366:
 
The iterator protocol methods are not usually called directly as Wren's 'for' statement (and the Sequence methods) call them automatically under the hood. However, in the spirit of this task, they are called directly.
<syntaxhighlight lang="ecmascriptwren">import "./llist" for DLinkedList
 
// Use iterators to print all elements of the sequence.
9,476

edits