This modules provides a new functional interface for Iterator.

Introduced classes

class ComparatorWith[E: nullable Object]

functional :: ComparatorWith

Comparator that use a function provided by the user to compare between elements.
class EnumerateIter[E: nullable Object]

functional :: EnumerateIter

An iterator that maps each item to a pair containing the item with its
class FilterIter[E: nullable Object]

functional :: FilterIter

An tierator that filter its element by a predicate pred.
class FlatMapIter[A: nullable Object, B: nullable Object]

functional :: FlatMapIter

An iterator that maps each item to an iterator and yield
class MapIter[A: nullable Object, B: nullable Object]

functional :: MapIter

An iterator that maps each item with f.
class OrderedIter[E: nullable Object]

functional :: OrderedIter

An iterator that yield each item in order

Redefined classes

redef class Array[E: nullable Object]

functional :: iter_extras $ Array

Resizable one dimension array of objects.
redef interface Iterator[E: nullable Object]

functional :: iter_extras $ Iterator

Iterators generate a series of elements, one at a time.

All class definitions

redef class Array[E: nullable Object]

functional :: iter_extras $ Array

Resizable one dimension array of objects.
class ComparatorWith[E: nullable Object]

functional $ ComparatorWith

Comparator that use a function provided by the user to compare between elements.
class EnumerateIter[E: nullable Object]

functional $ EnumerateIter

An iterator that maps each item to a pair containing the item with its
class FilterIter[E: nullable Object]

functional $ FilterIter

An tierator that filter its element by a predicate pred.
class FlatMapIter[A: nullable Object, B: nullable Object]

functional $ FlatMapIter

An iterator that maps each item to an iterator and yield
redef interface Iterator[E: nullable Object]

functional :: iter_extras $ Iterator

Iterators generate a series of elements, one at a time.
class MapIter[A: nullable Object, B: nullable Object]

functional $ MapIter

An iterator that maps each item with f.
class OrderedIter[E: nullable Object]

functional $ OrderedIter

An iterator that yield each item in order
package_diagram functional::iter_extras iter_extras functional::functional_types functional_types functional::iter_extras->functional::functional_types cartesian cartesian functional::iter_extras->cartesian core core functional::functional_types->core cartesian->core ...core ... ...core->core functional::functional functional functional::functional->functional::iter_extras a_star-m a_star-m a_star-m->functional::functional a_star-m... ... a_star-m...->a_star-m

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module cartesian

cartesian :: cartesian

Memory-efficient Cartesian products on heterogeneous collections.
module functional_types

functional :: functional_types

This module provides functional type to represents various function forms.

Children

module functional

functional :: functional

Functional types and functional API for Iterator

Descendants

module a_star-m

a_star-m

# This modules provides a new functional interface for `Iterator`.
module iter_extras

import functional_types
import cartesian

redef class Array

        # Sorts an array with a function.
        #
        # ~~~~nitish
        # class Person
        #       var name: String
        # end
        #
        # def get_name(p: Person) do return p.name
        #
        # var ps = [new Person("Turing"), new Person("Curry"), new Person("Alfredo")]
        # ps.sort_with(&get_name)
        # assert ps[0].name == "Alfredo"
        # assert ps[1].name == "Curry"
        # assert ps[2].name == "Turing"
        # ~~~~
        fun sort_with(f: Fun1[E, Comparable])
        do
                var cmp = new ComparatorWith[E](f)
                if length > 1 then
                        cmp.quick_sort(self, 0, length - 1)
                end
        end
end

redef interface Iterator[E]

        # Applies a function to every elements
        #
        # ~~~~nitish
        # fun add(x: Int): Int do return x + 1
        #
        # var f = &add
        # var xs = [1,2,3,4,5]
        # var actual = xs.iterator.map(f).to_a
        # assert actual == [2,3,4,5,6]
        # ~~~~
        fun map(f: Fun1[E,Object]): MapIter[E,Object]
        do
                return new MapIter[E,Object](self, f)
        end

        # Iterator that gives the current count and element as a pair
        fun enumerate: EnumerateIter[E]
        do
                return new EnumerateIter[E](self)
        end

        # Iterator that filters elements by a predicate
        #
        # ~~~~nitish
        # fun lt10(x: Int): Bool do return x < 10
        #
        # var pred = &lt10
        # var xs = [1..20]
        # var actual = xs.iterator.filter(pred).to_a
        # assert actual == [1..9].to_a
        # ~~~~
        fun filter(pred: Fun1[E,Bool]): FilterIter[E]
        do
                return new FilterIter[E](self,pred)
        end

        # Checks if at least one element respects a predicate
        #
        # ~~~~nitish
        # fun eq10(x: Int): Bool do return x == 10
        #
        # var pred = &eq10
        # var xs = [1,2,5,7,9,10,44]
        # assert xs.iterator.any(pred)
        # var ys = []
        # assert not ys.iterator.any(pred)
        # assert not [1,2,44].iterator.any(pred)
        # ~~~~
        fun any(pred: Fun1[E,Bool]): Bool
        do
                for x in self do
                        if pred.call(x) then
                                return true
                        end
                end
                return false
        end

        # Checks if all elements respect a predicate
        #
        # ~~~~nitish
        # fun lt10(x: Int): Bool do return x < 10
        #
        # var pred = &lt10
        # var xs = [1..9]
        # assert xs.iterator.all(pred)
        # assert [].iterator.all(pred)
        # assert not [1..10].iterator.all(pred)
        # ~~~~
        fun all(pred: Fun1[E,Bool]): Bool
        do
                for x in self do
                        if not pred.call(x) then
                                return false
                        end
                end
                return true
        end

        # Folds an iterator from the left
        #
        # ~~~~nitish
        # fun adder(x: Int, y: Int): Int do return x + y
        #
        # var xs = [1..10]
        # assert xs.iterator.fold(0, &adder) == 55
        # ~~~~
        fun fold(acc: Object, f: Fun2[Object, E, Object]): Object
        do
                for x in self do
                        acc = f.call(acc, x)
                end
                return acc
        end

        # Folds and apply two element at a time
        #
        # ~~~~nitish
        # fun min_int(x: Int, y: Int): Int
        # do
        #       if x < y then return x
        #       return y
        # end
        #
        # var xs = [100,423,51,1,-19,55,999,-18]
        # assert xs.iterator.fold1(&min_int) == -19
        # ~~~~
        # REQUIRE : length > 1
        fun fold1(f: Fun2[E,E,E]): E
        do
                var a1 = item
                next
                var a2 = item
                next
                var res = f.call(a1,a2)
                for x in self do
                        res = f.call(res, x)
                end
                return res
        end

        # Apply a mutation function over all elements
        #
        # ~~~~nitish
        # class Person
        #       var age: Int
        #       def incr_age
        #       do
        #               age += 1
        #       end
        # end
        #
        # var ps = [new Persone(1), new Person(2), new Person(3)]
        # var ages = ps.iterator.for_each(&Person::incr_age).map(&Person::age).to_a
        # assert ages == [2,3,4]
        # ~~~~
        fun for_each(f: Proc1[E])
        do
                for x in self do
                        f.call(x)
                end
        end

        # Maps every element to a nested structure then flattens it
        #
        # ~~~~nitish
        # fun chars_fn(s: String): Iterator[Char]
        # do
        #       return s.chars.iterator
        # end
        # var cs = ["aaa","bbb","ccc"]
        # assert cs.iterator.flat_map(&chars_fn).to_a.join == "aaabbbccc"
        # ~~~~
        fun flat_map(f: Fun1[E, Iterator[Object]]): FlatMapIter[E, Object]
        do
                return new FlatMapIter[E, Object](self, f)
        end

        # Generates an `Iterator` whose elements are sorted by the function
        # passed in argument.
        #
        # ~~~~nitish
        # class Person
        #       var name: String
        # end
        #
        # def get_name(p: Person) do return p.name
        #
        # var ps = [new Person("Turing"), new Person("Curry"), new Person("Alfredo")]
        # var ordered_names = ps.iterator.order_by(&get_name).map(&get_name).to_a
        # assert ordered_names == ["Alfredo", "Curry", "Turing"]
        # ~~~~
        fun order_by(f: Fun1[E, Comparable]): OrderedIter[E]
        do
                return new OrderedIter[E](self, f)
        end

end

# Base class for all iterators using functional types.
private abstract class FunIter[OLD,NEW]
        super Iterator[NEW]
        var my_iter: Iterator[OLD]

        redef fun next
        do
                my_iter.next
        end

        redef fun start
        do
                my_iter.start
        end

        redef fun finish
        do
                my_iter.finish
        end

        redef fun is_ok
        do
                return my_iter.is_ok
        end
end

# An iterator that maps each item with `f`.
class MapIter[A,B]
        super FunIter[A,B]
        var f: Fun1[A, B]

        redef fun item
        do
                return f.call(my_iter.item)
        end

end

# An iterator that maps each item to a pair containing the item with its
# current count.
class EnumerateIter[E]
        super FunIter[E, Pair[Int,E]]

        redef fun item
        do
               return new Pair[Int,E](0, my_iter.item)
        end
end

# An tierator that filter its element by a predicate `pred`.
class FilterIter[E]
        super FunIter[E,nullable E]
        var pred: Fun1[E, Bool]

        redef init
        do
                if is_ok and not pred.call(my_iter.item) then next
        end

        redef fun item
        do
                assert is_ok
                return my_iter.item
        end

        redef fun next
        do
                loop
                        my_iter.next
                        if not is_ok then
                                break
                        end
                        var x = my_iter.item
                        if pred.call(x) then
                                break
                        end
                end
        end
end

# An iterator that maps each item to an iterator and yield
# each item from it.
class FlatMapIter[A,B]
        super FunIter[A,B]
        var f: Fun1[A, Iterator[B]]
        protected var inner: nullable Iterator[B] = null

        redef init
        do
                try_compute_inner
        end

        redef fun item
        do
                return inner.as(not null).item
        end

        redef fun is_ok
        do
                return inner != null
        end

        redef fun next
        do
                inner.next
                if not inner.is_ok then
                        super
                        try_compute_inner
                end
        end

        # Tries to resolve the inner iterator.
        # Assigns null to `inner` if it fails.
        protected fun try_compute_inner
        do
                inner = null
                if not my_iter.is_ok then return
                var res = f.call(my_iter.item)
                if res.is_ok then inner = res
        end
end

# An iterator that yield each item in order
class OrderedIter[E]
        super FunIter[E,E]
        var f: Fun1[E, Comparable]

        private var sorted_iter: Iterator[E] is noinit
        private var sorted_arr: Array[E] is noinit

        redef init
        do
                sorted_arr = my_iter.to_a
                sorted_arr.sort_with(f)
                sorted_iter = sorted_arr.iterator
        end

        redef fun next
        do
                sorted_iter.next
        end

        redef fun item
        do
                return sorted_iter.item
        end

        redef fun is_ok
        do
                return sorted_iter.is_ok
        end

        redef fun finish
        do
                sorted_iter.finish
        end

        redef fun to_a
        do
                return sorted_arr
        end
end

# Comparator that use a function provided by the user to compare between elements.
class ComparatorWith[E]
        super Comparator
        redef type COMPARED: E

        var f: Fun1[E, Comparable]

        redef fun compare(a,b)
        do
                var x = f.call(a)
                var y = f.call(b)
                if x < y then return -1
                if x > y then return 1
                return 0
        end
end
lib/functional/iter_extras.nit:17,1--408,3