Iterator

Last updated

In computer programming, an iterator is an object that enables a programmer to traverse a container, particularly lists. [1] [2] [3] Various types of iterators are often provided via a container's interface. Though the interface and semantics of a given iterator are fixed, iterators are often implemented in terms of the structures underlying a container implementation and are often tightly coupled to the container to enable the operational semantics of the iterator. An iterator performs traversal and also gives access to data elements in a container, but does not itself perform iteration (i.e., not without some significant liberty taken with that concept or with trivial use of the terminology)[ citation needed ].

Contents

An iterator is behaviorally similar to a database cursor. Iterators date to the CLU programming language in 1974.

Description

Internal Iterators

Internal iterators are higher order functions (often taking anonymous functions, but not necessarily) such as map(), reduce() etc., implementing the traversal across a container, applying the given function to every element in turn. An example might be Python's map function:

digits=[0,1,2,3,4,5,6,7,8,9]squared_digits=map(lambdax:x**2,digits)# Iterating over this iterator would result in 0, 1, 4, 9, 16, ..., 81.

External iterators and the iterator pattern

An external iterator may be thought of as a type of pointer that has two primary operations: referencing one particular element in the object collection (called element access), and modifying itself so it points to the next element (called element traversal). [4] There must also be a way to create an iterator so it points to some first element as well as some way to determine when the iterator has exhausted all of the elements in the container. Depending on the language and intended use, iterators may also provide additional operations or exhibit different behaviors.

The primary purpose of an iterator is to allow a user to process every element of a container while isolating the user from the internal structure of the container. [2] This allows the container to store elements in any manner it wishes while allowing the user to treat it as if it were a simple sequence or list. An iterator class is usually designed in tight coordination with the corresponding container class. Usually, the container provides the methods for creating iterators.

A loop counter is sometimes also referred to as a loop iterator. A loop counter, however, only provides the traversal functionality and not the element access functionality.

Generators

One way of implementing iterators is to use a restricted form of coroutine, known as a generator. By contrast with a subroutine, a generator coroutine can yield values to its caller multiple times, instead of returning just once. Most iterators are naturally expressible as generators, but because generators preserve their local state between invocations, they're particularly well-suited for complicated, stateful iterators, such as tree traversers. There are subtle differences and distinctions in the use of the terms "generator" and "iterator", which vary between authors and languages. [5] In Python, a generator is an iterator constructor: a function that returns an iterator. An example of a Python generator returning an iterator for the Fibonacci numbers using Python's yield statement follows:

deffibonacci(limit):a,b=0,1for_inrange(limit):yieldaa,b=b,a+bfornumberinfibonacci(100):# The generator constructs an iteratorprint(number)

Implicit iterators

Some object-oriented languages such as C#, C++ (later versions), Delphi (later versions), Go, Java (later versions), Lua, Perl, Python, Ruby provide an intrinsic way of iterating through the elements of a container object without the introduction of an explicit iterator object. An actual iterator object may exist in reality, but if it does it is not exposed within the source code of the language. [4] [6]

Implicit iterators are often manifested by a "foreach" statement (or equivalent), such as in the following Python example:

forvalueiniterable:print(value)

In Python, an iterable is an object which can be converted to an iterator, which is then iterated through during the for loop; this is done implicitly.

Or other times they may be created by the collection object itself, as in this Ruby example:

iterable.eachdo|value|putsvalueend

This iteration style is sometimes called "internal iteration" because its code fully executes within the context of the iterable object (that controls all aspects of iteration), and the programmer only provides the operation to execute at each step (using an anonymous function).

Languages that support list comprehensions or similar constructs may also make use of implicit iterators during the construction of the result list, as in Python:

names=[person.nameforpersoninrosterifperson.male]

Sometimes the implicit hidden nature is only partial. The C++ language has a few function templates for implicit iteration, such as for_each(). These functions still require explicit iterator objects as their initial input, but the subsequent iteration does not expose an iterator object to the user.

Streams

Iterators are a useful abstraction of input streams – they provide a potentially infinite iterable (but not necessarily indexable) object. Several languages, such as Perl and Python, implement streams as iterators. In Python, iterators are objects representing streams of data. [7] Alternative implementations of stream include data-driven languages, such as AWK and sed.

Contrasting with indexing

In procedural languages it is common to use the subscript operator and a loop counter to loop through all the elements in a sequence such as an array. Although indexing may also be used with some object-oriented containers, the use of iterators may have some advantages: [8]

The ability of a container to be modified while iterating through its elements has become necessary in modern object-oriented programming, where the interrelationships between objects and the effects of operations may not be obvious. By using an iterator one is isolated from these sorts of consequences. This assertion must however be taken with a grain of salt, because more often than not, for efficiency reasons, the iterator implementation is so tightly bound to the container that it does preclude modification of the underlying container without invalidating itself.

For containers that may move around their data in memory, the only way to not invalidate the iterator is, for the container, to somehow keep track of all the currently alive iterators and update them on the fly. Since the number of iterators at a given time may be arbitrarily large in comparison to the size of the tied container, updating them all will drastically impair the complexity guarantee on the container's operations.

An alternative way to keep the number of updates bound relatively to the container size would be to use a kind of handle mechanism, that is a collection of indirect pointers to the container's elements that must be updated with the container, and let the iterators point to these handles instead of directly to the data elements. But this approach will negatively impact the iterator performance, since it must effectuate a double pointer following to access the actual data element. This is usually not desirable, because many algorithms using the iterators invoke the iterators data access operation more often than the advance method. It is therefore especially important to have iterators with very efficient data access.

All in all, this is always a trade-off between security (iterators remain always valid) and efficiency. Most of the time, the added security is not worth the efficiency price to pay for it. Using an alternative container (for example a singly linked list instead of a vector) would be a better choice (globally more efficient) if the stability of the iterators is needed.

Classifying iterators

Iterator categories

Iterators can be categorised according to their functionality. Here is a (non-exhaustive) list of iterator categories: [9] [10]

CategoryLanguages
Bidirectional iterator C++
Forward iteratorC++
Input iteratorC++
Output iteratorC++
Random access iteratorC++
Trivial iteratorC++ (old STL) [11]

Iterator types

Different languages or libraries used with these languages define iterator types. Some of them are [12]

TypeLanguages
Array iterator PHP, R [13]
Caching iteratorPHP
Constant iterator C++, [14] PHP
Directory iteratorPHP, Python
Filter iteratorPHP, R
Limit iteratorPHP
List iterator Java, [6] R
Recursive array iteratorPHP
XML iteratorPHP

In different programming languages

C# and other .NET languages

Iterators in the .NET Framework are called "enumerators" and represented by the IEnumerator interface. [15] :189–190,344 [16] :53–54IEnumerator provides a MoveNext() method, which advances to the next element and indicates whether the end of the collection has been reached; [15] :344 [16] :55–56 [17] :89 a Current property, to obtain the value of the element currently being pointed at. [15] :344 [16] :56 [17] :89 and an optional Reset() method, [15] :344 to rewind the enumerator back to its initial position. The enumerator initially points to a special value before the first element, so a call to MoveNext() is required to begin iterating.

Enumerators are typically obtained by calling the GetEnumerator() method of an object implementing the IEnumerable interface. [16] :54–56 [17] :54–56 a Current property, to obtain the value of the element currently being pointed at; [15] :344 [16] :56 [17] :89Container classes typically implement this interface. However, the foreach statement in C# can operate on any object providing such a method, even if it does not implement IEnumerable (duck typing). [17] :89 Both interfaces were expanded into generic versions in .NET 2.0.

The following shows a simple use of iterators in C# 2.0:

// explicit versionIEnumerator<MyType>iter=list.GetEnumerator();while(iter.MoveNext())Console.WriteLine(iter.Current);// implicit versionforeach(MyTypevalueinlist)Console.WriteLine(value);

C# 2.0 also supports generators: a method that is declared as returning IEnumerator (or IEnumerable), but uses the "yield return" statement to produce a sequence of elements instead of returning an object instance, will be transformed by the compiler into a new class implementing the appropriate interface.

C++

The C++ language makes wide use of iterators in its Standard Library and describes several categories of iterators differing in the repertoire of operations they allow. These include forward iterators, bidirectional iterators, and random access iterators, in order of increasing possibilities. All of the standard container template types provide iterators of one of these categories. Iterators generalize pointers to elements of an array (which indeed can be used as iterators), and their syntax is designed to resemble that of C pointer arithmetic, where the * and -> operators are used to reference the element to which the iterator points and pointer arithmetic operators like ++ are used to modify iterators in the traversal of a container.

Traversal using iterators usually involves a single varying iterator, and two fixed iterators that serve to delimit a range to be traversed. The distance between the limiting iterators, in terms of the number of applications of the operator ++ needed to transform the lower limit into the upper one, equals the number of items in the designated range; the number of distinct iterator values involved is one more than that. By convention, the lower limiting iterator "points to" the first element in the range, while the upper limiting iterator does not point to any element in the range, but rather just beyond the end of the range. For traversal of an entire container, the begin() method provides the lower limit, and end() the upper limit. The latter does not reference any element of the container at all but is a valid iterator value that can be compared against.

The following example shows a typical use of an iterator.

std::vector<int>items;items.push_back(5);// Append integer value '5' to vector 'items'.items.push_back(2);// Append integer value '2' to vector 'items'.items.push_back(9);// Append integer value '9' to vector 'items'.for(autoit=items.begin();it!=items.end();++it){// Iterate through 'items'.std::cout<<*it;// And print value of 'items' for current index.}// In C++11, the same can be done without using any iterators:for(autox:items){std::cout<<x;// Print value of each element 'x' of 'items'.}// Both of the for loops print "529".

Iterator types are separate from the container types they are used with, though the two are often used in concert. The category of the iterator (and thus the operations defined for it) usually depends on the type of container, with for instance arrays or vectors providing random access iterators, but sets (which use a linked structure as implementation) only providing bidirectional iterators. One same container type can have more than one associated iterator type; for instance the std::vector<T> container type allows traversal either using (raw) pointers to its elements (of type *<T>), or values of a special type std::vector<T>::iterator, and yet another type is provided for "reverse iterators", whose operations are defined in such a way that an algorithm performing a usual (forward) traversal will actually do traversal in reverse order when called with reverse iterators. Most containers also provide a separate const_iterator type, for which operations that would allow changing the values pointed to are intentionally not defined.

Simple traversal of a container object or a range of its elements (including modification of those elements unless a const_iterator is used) can be done using iterators alone. But container types may also provide methods like insert or erase that modify the structure of the container itself; these are methods of the container class, but in addition require one or more iterator values to specify the desired operation. While it is possible to have multiple iterators pointing into the same container simultaneously, structure-modifying operations may invalidate certain iterator values (the standard specifies for each case whether this may be so); using an invalidated iterator is an error that will lead to undefined behavior, and such errors need not be signaled by the run time system.

Implicit iteration is also partially supported by C++ through the use of standard function templates, such as std::for_each() , std::copy() and std::accumulate() .

When used they must be initialized with existing iterators, usually begin and end, that define the range over which iteration occurs. But no explicit iterator object is subsequently exposed as the iteration proceeds. This example shows the use of for_each.

ContainerType<ItemType>c;// Any standard container type of ItemType elements.voidProcessItem(constItemType&i){// Function that will process each item of the collection.std::cout<<i<<std::endl;}std::for_each(c.begin(),c.end(),ProcessItem);// A for-each iteration loop.

The same can be achieved using std::copy, passing a std::ostream_iterator value as third iterator:

std::copy(c.begin(),c.end(),std::ostream_iterator<ItemType>(std::cout,"\n"));

Since C++11, lambda function syntax can be used to specify to operation to be iterated inline, avoiding the need to define a named function. Here is an example of for-each iteration using a lambda function:

ContainerType<ItemType>c;// Any standard container type of ItemType elements.// A for-each iteration loop with a lambda function.std::for_each(c.begin(),c.end(),[](constItemType&i){std::cout<<i<<std::endl;});

Java

Introduced in the Java JDK 1.2 release, the java.util.Iterator interface allows the iteration of container classes. Each Iterator provides a next() and hasNext() method, [18] :294–295 and may optionally support a remove() [18] :262,266 method. Iterators are created by the corresponding container class, typically by a method named iterator(). [19] [18] :99 [18] :217

The next() method advances the iterator and returns the value pointed to by the iterator. The first element is obtained upon the first call to next(). [18] :294–295 To determine when all the elements in the container have been visited the hasNext() test method is used. [18] :262 The following example shows a simple use of iterators:

Iteratoriter=list.iterator();// Iterator<MyType> iter = list.iterator(); // in J2SE 5.0while(iter.hasNext()){System.out.print(iter.next());if(iter.hasNext())System.out.print(", ");}

To show that hasNext() can be called repeatedly, we use it to insert commas between the elements but not after the last element.

This approach does not properly separate the advance operation from the actual data access. If the data element must be used more than once for each advance, it needs to be stored in a temporary variable. When an advance is needed without data access (i.e. to skip a given data element), the access is nonetheless performed, though the returned value is ignored in this case.

For collection types that support it, the remove() method of the iterator removes the most recently visited element from the container while keeping the iterator usable. Adding or removing elements by calling the methods of the container (also from the same thread) makes the iterator unusable. An attempt to get the next element throws the exception. An exception is also thrown if there are no more elements remaining (hasNext() has previously returned false).

Additionally, for java.util.List there is a java.util.ListIterator with a similar API but that allows forward and backward iteration, provides its current index in the list and allows setting of the list element at its position.

The J2SE 5.0 release of Java introduced the Iterable interface to support an enhanced for (foreach) loop for iterating over collections and arrays. Iterable defines the iterator() method that returns an Iterator. [18] :266 Using the enhanced for loop, the preceding example can be rewritten as

for(MyTypeobj:list){System.out.print(obj);}

Some containers also use the older (since 1.0) Enumeration class. It provides hasMoreElements() and nextElement() methods but has no methods to modify the container.

Scala

In Scala, iterators have a rich set of methods similar to collections, and can be used directly in for loops. Indeed, both iterators and collections inherit from a common base trait - scala.collection.TraversableOnce. However, because of the rich set of methods available in the Scala collections library, such as map, collect, filter etc., it is often not necessary to deal with iterators directly when programming in Scala.

Java iterators and collections can be automatically converted into Scala iterators and collections, respectively, simply by adding the single line

importscala.collection.JavaConversions._

to the file. The JavaConversions object provides implicit conversions to do this. Implicit conversions are a feature of Scala: methods that, when visible in the current scope, automatically insert calls to themselves into relevant expressions at the appropriate place to make them typecheck when they otherwise would not.

MATLAB

MATLAB supports both external and internal implicit iteration using either "native" arrays or cell arrays. In the case of external iteration where the onus is on the user to advance the traversal and request next elements, one can define a set of elements within an array storage structure and traverse the elements using the for-loop construct. For example,

% Define an array of integersmyArray=[1,3,5,7,11,13];forn=myArray% ... do something with ndisp(n)% Echo integer to Command Windowend

traverses an array of integers using the for keyword.

In the case of internal iteration where the user can supply an operation to the iterator to perform over every element of a collection, many built-in operators and MATLAB functions are overloaded to execute over every element of an array and return a corresponding output array implicitly. Furthermore, the arrayfun and cellfun functions can be leveraged for performing custom or user defined operations over "native" arrays and cell arrays respectively. For example,

functionsimpleFun% Define an array of integersmyArray=[1,3,5,7,11,13];% Perform a custom operation over each element myNewArray=arrayfun(@(a)myCustomFun(a),myArray);% Echo resulting array to Command WindowmyNewArrayfunctionoutScalar=myCustomFun(inScalar)% Simply multiply by 2outScalar=2*inScalar;

defines a primary function simpleFun that implicitly applies custom subfunction myCustomFun to each element of an array using built-in function arrayfun.

Alternatively, it may be desirable to abstract the mechanisms of the array storage container from the user by defining a custom object-oriented MATLAB implementation of the Iterator Pattern. Such an implementation supporting external iteration is demonstrated in MATLAB Central File Exchange item Design Pattern: Iterator (Behavioral). This is written in the new class-definition syntax introduced with MATLAB software version 7.6 (R2008a) and features a one-dimensional cell array realization of the List Abstract Data Type (ADT) as the mechanism for storing a heterogeneous (in data type) set of elements. It provides the functionality for explicit forward List traversal with the hasNext(), next() and reset() methods for use in a while-loop.

PHP

UML class diagram of the Iterator interface in PHP UML PHP iterator interface.svg
UML class diagram of the Iterator interface in PHP

PHP's foreach loop was introduced in version 4.0 and made compatible with objects as values in 4.0 Beta 4. [20] However, support for iterators was added in PHP 5 through the introduction of the internal [21] Traversable interface. [22] The two main interfaces for implementation in PHP scripts that enable objects to be iterated via the foreach loop are Iterator and IteratorAggregate. The latter does not require the implementing class to declare all required methods, instead it implements an accessor method (getIterator) that returns an instance of Traversable. The Standard PHP Library provides several classes to work with special iterators. [23] PHP also supports Generators since 5.5. [24]

The simplest implementation is by wrapping an array, this can be useful for type hinting and information hiding.

namespaceWikipedia\Iterator;finalclassArrayIteratorextends\Iterator{privatearray$array;publicfunction__construct(array$array){$this->array=$array;}publicfunctionrewind():void{echo'rewinding',PHP_EOL;reset($this->array);}publicfunctioncurrent(){$value=current($this->array);echo"current: {$value}",PHP_EOL;return$value;}publicfunctionkey(){$key=key($this->array);echo"key: {$key}",PHP_EOL;return$key;}publicfunctionnext(){$value=next($this->array);echo"next: {$value}",PHP_EOL;return$value;}publicfunctionvalid():bool{$valid=$this->current()!==false;echo'valid: ',($valid?'true':'false'),PHP_EOL;return$valid;}}

All methods of the example class are used during the execution of a complete foreach loop (foreach ($iterator as $key => $current) {}). The iterator's methods are executed in the following order:

  1. $iterator->rewind() ensures that the internal structure starts from the beginning.
  2. $iterator->valid() returns true in this example.
  3. $iterator->current() returned value is stored in $value.
  4. $iterator->key() returned value is stored in $key.
  5. $iterator->next() advances to the next element in the internal structure.
  6. $iterator->valid() returns false and the loop is aborted.

The next example illustrates a PHP class that implements the Traversable interface, which could be wrapped in an IteratorIterator class to act upon the data before it is returned to the foreach loop. The usage together with the MYSQLI_USE_RESULT constant allows PHP scripts to iterate result sets with billions of rows with very little memory usage. These features are not exclusive to PHP nor to its MySQL class implementations (e.g. the PDOStatement class implements the Traversable interface as well).

mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT);$mysqli=new\mysqli('host.example.com','username','password','database_name');// The \mysqli_result class that is returned by the method call implements the internal Traversable interface.foreach($mysqli->query('SELECT `a`, `b`, `c` FROM `table`',MYSQLI_USE_RESULT)as$row){// Act on the returned row, which is an associative array.}

Python

Iterators in Python are a fundamental part of the language and in many cases go unseen as they are implicitly used in the for (foreach) statement, in list comprehensions, and in generator expressions. All of Python's standard built-in collection types support iteration, as well as many classes that are part of the standard library. The following example shows typical implicit iteration over a sequence:

forvalueinsequence:print(value)

Python dictionaries (a form of associative array) can also be directly iterated over, when the dictionary keys are returned; or the items() method of a dictionary can be iterated over where it yields corresponding key,value pairs as a tuple:

forkeyindictionary:value=dictionary[key]print(key,value)
forkey,valueindictionary.items():print(key,value)

Iterators however can be used and defined explicitly. For any iterable sequence type or class, the built-in function iter() is used to create an iterator object. The iterator object can then be iterated with the next() function, which uses the __next__() method internally, which returns the next element in the container. (The previous statement applies to Python 3.x. In Python 2.x, the next() method is equivalent.) A StopIteration exception will be raised when no more elements are left. The following example shows an equivalent iteration over a sequence using explicit iterators:

it=iter(sequence)whileTrue:try:value=it.next()# in Python 2.xvalue=next(it)# in Python 3.xexceptStopIteration:breakprint(value)

Any user-defined class can support standard iteration (either implicit or explicit) by defining an __iter__() method that returns an iterator object. The iterator object then needs to define a __next__() method that returns the next element.

Python's generators implement this iteration protocol.

Raku

Iterators in Raku are a fundamental part of the language, although usually users do not have to care about iterators. Their usage is hidden behind iteration APIs such as the for statement, map, grep, list indexing with .[$idx], etc.

The following example shows typical implicit iteration over a collection of values:

my@values = 1, 2, 3; for@values -> $value {     say$value } # OUTPUT:# 1# 2# 3

Raku hashes can also be directly iterated over; this yields key-value Pair objects. The kv method can be invoked on the hash to iterate over the key and values; the keys method to iterate over the hash's keys; and the values method to iterate over the hash's values.

my%word-to-number = 'one' => 1, 'two' => 2, 'three' => 3; for%word-to-number -> $pair {     say$pair; } # OUTPUT:# three => 3# one => 1# two => 2for%word-to-number.kv -> $key, $value {     say"$key: $value"  } # OUTPUT:# three: 3# one: 1# two: 2for%word-to-number.keys -> $key {     say"$key => " ~ %word-to-number{$key}; } # OUTPUT:# three => 3# one => 1# two => 2

Iterators however can be used and defined explicitly. For any iterable type, there are several methods that control different aspects of the iteration process. For example, the iterator method is supposed to return an Iterator object, and the pull-one method is supposed to produce and return the next value if possible, or return the sentinel value IterationEnd if no more values could be produced. The following example shows an equivalent iteration over a collection using explicit iterators:

my@values = 1, 2, 3; my$it := @values.iterator;          # grab iterator for @valuesloop {     my$value := $it.pull-one;       # grab iteration's next valuelastif$value =:= IterationEnd; # stop if we reached iteration's endsay$value; } # OUTPUT:# 1# 2# 3

All iterable types in Raku compose the Iterable role, Iterator role, or both. The Iterable is quite simple and only requires the iterator to be implemented by the composing class. The Iterator is more complex and provides a series of methods such as pull-one, which allows for a finer operation of iteration in several contexts such as adding or eliminating items, or skipping over them to access other items. Thus, any user-defined class can support standard iteration by composing these roles and implementing the iterator and/or pull-one methods.

The DNA class represents a DNA strand and implements the iterator by composing the Iterable role. The DNA strand is split into a group of trinucleotides when iterated over:

subsetStrandofStrwhere { .match(/^^ <[ACGT]>+ $$/) and .chars %% 3 }; classDNAdoesIterable {     has$.chain;     methodnew(Strand:D$chain) {         self.bless: :$chain     }       methoditerator(DNA:D:){ $.chain.comb.rotor(3).iterator } };  forDNA.new('GATTACATA') {     .say } # OUTPUT:# (G A T)# (T A C)# (A T A)sayDNA.new('GATTACATA').map(*.join).join('-'); # OUTPUT:# GAT-TAC-ATA

The Repeater class composes both the Iterable and Iterator roles:

classRepeaterdoesIterabledoesIterator {     hasAny$.itemisrequired;     hasInt$.timesisrequired;     hasInt$!count = 1;          multimethodnew($item, $times) {         self.bless: :$item, :$times;     }          methoditerator { self }     methodpull-one(--> Mu){          if$!count <= $!times {             $!count += 1;             return$!item         }         else {             returnIterationEnd         }     } }  forRepeater.new("Hello", 3) {     .say }  # OUTPUT:# Hello# Hello# Hello

Ruby

Ruby implements iterators quite differently; all iterations are done by means of passing callback closures to container methods - this way Ruby not only implements basic iteration but also several patterns of iteration like function mapping, filters and reducing. Ruby also supports an alternative syntax for the basic iterating method each, the following three examples are equivalent:

(0...42).eachdo|n|putsnend

...and...

fornin0...42putsnend

or even shorter

42.timesdo|n|putsnend

Ruby can also iterate over fixed lists by using Enumerators and either calling their #next method or doing a for each on them, as above.

Rust

Rust makes use of external iterators throughout the standard library, including in its for loop, which implicitly calls the next() method of an iterator until it is consumed. The most basic for loop for example iterates over a Range type:

foriin0..42{println!("{}",i);}// Prints the numbers 0 to 41

Specifically, the for loop will call a value's into_iter() method, which returns an iterator that in turn yields the elements to the loop. The for loop (or indeed, any method that consumes the iterator), proceeds until the next() method returns a None value (iterations yielding elements return a Some(T) value, where T is the element type).

All collections provided by the standard library implement the IntoIterator trait (meaning they define the into_iter() method). Iterators themselves implement the Iterator trait, which requires defining the next() method. Furthermore, any type implementing Iterator is automatically provided an implementation for IntoIterator that returns itself.

Iterators support various adapters (map(), filter(), skip(), take(), etc.) as methods provided automatically by the Iterator trait.

Users can create custom iterators by creating a type implementing the Iterator trait. Custom collections can implement the IntoIterator trait and return an associated iterator type for their elements, enabling their use directly in for loops. Below, the Fibonacci type implements a custom, unbounded iterator:

structFibonacci(u64,u64);implFibonacci{pubfnnew()-> Self{Self(0,1)}}implIteratorforFibonacci{typeItem=u64;fnnext(&mutself)-> Option<Self::Item>{letnext=self.0;self.0=self.1;self.1=self.0+next;Some(next)}}letfib=Fibonacci::new();forninfib.skip(1).step_by(2).take(4){println!("{n}");}// Prints 1, 2, 5, and 13

See also

Related Research Articles

<span class="mw-page-title-main">Heap (data structure)</span> Computer science data structure

In computer science, a heap is a tree-based data structure that satisfies the heap property: In a max heap, for any given node C, if P is a parent node of C, then the key of P is greater than or equal to the key of C. In a min heap, the key of P is less than or equal to the key of C. The node at the "top" of the heap is called the root node.

In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed and which also avoids repeated evaluations.

A visitor pattern is a software design pattern that separates the algorithm from the object structure. Because of this separation, new operations can be added to existing object structures without modifying the structures. It is one way to follow the open/closed principle in object-oriented programming and software engineering.

In computer science, control flow is the order in which individual statements, instructions or function calls of an imperative program are executed or evaluated. The emphasis on explicit control flow distinguishes an imperative programming language from a declarative programming language.

Generic programming is a style of computer programming in which algorithms are written in terms of data types to-be-specified-later that are then instantiated when needed for specific types provided as parameters. This approach, pioneered by the ML programming language in 1973, permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplicate code.

In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled.

In computer science, a set is an abstract data type that can store unique values, without any particular order. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for membership in a set.

<span class="mw-page-title-main">D (programming language)</span> Multi-paradigm system programming language

D, also known as dlang, is a multi-paradigm system programming language created by Walter Bright at Digital Mars and released in 2001. Andrei Alexandrescu joined the design and development effort in 2007. Though it originated as a re-engineering of C++, D is now a very different language drawing inspiration from other high-level programming languages, notably Java, Python, Ruby, C#, and Eiffel.

<span class="mw-page-title-main">For loop</span> Control flow statement for repeated execution

In computer science a for-loop or for loop is a control flow statement for specifying iteration. Specifically, a for loop functions by running a section of code repeatedly until a certain condition has been satisfied.

In computer programming, a function object is a construct allowing an object to be invoked or called as if it were an ordinary function, usually with the same syntax. In some languages, particularly C++, function objects are often called functors.

In computer science, a generator is a routine that can be used to control the iteration behaviour of a loop. All generators are also iterators. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values. However, instead of building an array containing all the values and returning them all at once, a generator yields the values one at a time, which requires less memory and allows the caller to get started processing the first few values immediately. In short, a generator looks like a function but behaves like an iterator.

<span class="mw-page-title-main">Foreach loop</span> Control flow statement for traversing items in a collection

In computer programming, foreach loop is a control flow statement for traversing items in a collection. foreach is usually used in place of a standard for loop statement. Unlike other for loop constructs, however, foreach loops usually maintain no explicit counter: they essentially say "do this to everything in this set", rather than "do this x times". This avoids potential off-by-one errors and makes code simpler to read. In object-oriented languages, an iterator, even if implicit, is often used as the means of traversal.

In the Perl programming language, autovivification is the automatic creation of new arrays and hashes as required every time an undefined value is dereferenced. Perl autovivification allows a programmer to refer to a structured variable, and arbitrary sub-elements of that structured variable, without expressly declaring the existence of the variable and its complete structure beforehand.

<span class="mw-page-title-main">Java collections framework</span> Collections in Java

The Java collections framework is a set of classes and interfaces that implement commonly reusable collection data structures.

C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

This article describes the syntax of the C# programming language. The features described are compatible with .NET Framework and Mono.

This Comparison of programming languages (associative arrays) compares the features of associative array data structures or array-lookup processing for over 40 computer programming languages.

The syntax and semantics of PHP, a programming language, form a set of rules that define how a PHP program can be written and interpreted.

In C++, associative containers refer to a group of class templates in the standard library of the C++ programming language that implement ordered associative arrays. Being templates, they can be used to store arbitrary elements, such as integers or custom classes. The following containers are defined in the current revision of the C++ standard: set, map, multiset, multimap. Each of these containers differ only on constraints placed on their elements.

References

  1. Gatcomb, Joshua (Jun 16, 2005). "Understanding and Using Iterators". Perl.com. Retrieved 2012-08-08. A user-defined iterator usually takes the form of a code reference that, when executed, calculates the next item in a list and returns it. When the iterator reaches the end of the list, it returns an agreed-upon value.
  2. 1 2 Watt, Stephen M. (September 16, 2006). "A Technique for Generic Iteration and Its Optimization" (PDF). The University of Western Ontario, Department of Computer Science. Retrieved 2012-08-08. Iterators were introduced as constructs to allow looping over abstract data structures without revealing their internal representation.
  3. Alex Allain. "STL Iterators". Cprogramming.com - Your resource for C and C++. Retrieved 2012-08-08. You can think of an iterator as pointing to an item that is part of a larger container of items.
  4. 1 2 "Difference between an external iterator and an internal iterator". CareerRide.COM. 2009-04-03. Archived from the original on 2012-09-19. Retrieved 2012-08-08. An internal iterator is implemented by the member functions of the class which has the iteration logic. An external iterator is implemented by a separate class which can be attached to the object which has iteration logic. The advantage of external iterator is that, many iterators can be made active simultaneously on the existing or same object.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  5. Watt, Stephen M. "A Technique for Generic Iteration and Its Optimization". The University of Western Ontario, Department of Computer Science. Archived from the original on 2012-08-06. Retrieved 2012-08-08. Some authors use the term iterator, and others the term generator. Some make subtle distinctions between the two.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  6. 1 2 Freeman, Eric; Freeman, Elisabeth; Kathy, Sierra; Bert, Bates (2004). Hendrickson, Mike; Loukides, Mike (eds.). Head First Design Patterns (paperback). Vol. 1. O'REILLY. p. 338. ISBN   978-0-596-00712-6 . Retrieved 2012-08-09.
  7. "Glossary — Python 3.8.4 documentation" . Retrieved 2020-07-15.
  8. Vecerina, Ivan (2006-02-01). "index vs iterator". BYTES. Archived from the original on 2012-08-09. Retrieved 2012-08-08. An index only can be used for containers that (efficiently) support random access (i.e. direct access to an element at a given position). An iterator is a more general concept. Iterators offer efficient traversal of linked lists, files, and a number of other data structures. It often leads to the generation of more efficient code.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  9. Kevin Waterson. "C++ Iteratoren: Iterator-Kategorien" (in German). cppreference.com. Retrieved 2012-08-09.
  10. Kevin Waterson. "Iterators: Concepts". sgi. Retrieved 2012-08-09.
  11. larsmans (2011-03-06). "Types of iterator: Output vs. input vs. forward vs. random access iterator". stackoverflow. Archived from the original on 2012-08-08. Retrieved 2012-08-09.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  12. Kevin Waterson. "Introduction to SPL: Introduction to Standard PHP Library (SPL)". PHPRO.ORG. Retrieved 2012-08-09.
  13. Collier, Andrew. "Iterators in R". Archived from the original on 18 October 2018. Retrieved 16 November 2013.
  14. "concurrent_unordered_set Template Class". Intel Threading Building Blocks for Open Source. Archived from the original on 2015-05-01. Retrieved 2012-08-09. •The iterator types iterator and const_iterator are of the forward iterator category
  15. 1 2 3 4 5 Albahari, Joseph. C# 10 in a Nutshell. O'Reilly. ISBN   978-1-098-12195-2.
  16. 1 2 3 4 5 Skeet, Jon. C# in Depth. Manning. ISBN   978-1617294532.
  17. 1 2 3 4 5 Price, Mark J. C# 8.0 and .NET Core 3.0 – Modern Cross-Platform Development: Build Applications with C#, .NET Core, Entity Framework Core, ASP.NET Core, and ML.NET Using Visual Studio Code. Packt. ISBN   978-1-098-12195-2.
  18. 1 2 3 4 5 6 7 Bloch, Joshua (2018). "Effective Java: Programming Language Guide" (third ed.). Addison-Wesley. ISBN   978-0134685991.
  19. "java.util: Interface Iterator<E>: Method Summary". Oracle. Retrieved 2012-08-08.
  20. "PHP 4 ChangeLog". The PHP Group. 2000-02-20. Retrieved 2015-10-13.
  21. Internal refers to the fact that the interface cannot be implemented in PHP scripts, only in the C (programming language) source.
  22. "The Traversable interface". The PHP Group. Retrieved 2015-10-13.
  23. "Iterators". The PHP Group. Retrieved 2015-10-13.
  24. "PHP 5 ChangeLog". The PHP Group. 2013-06-20. Retrieved 2015-10-13.