Iterators and Enumerables #12

Merged
emirpasic merged 26 commits from enums into master 2016-06-24 05:15:08 +00:00
emirpasic commented 2016-06-23 10:15:53 +00:00 (Migrated from github.com)

Closes #8

Iterator

Added stateful iterator to all ordered containers:

  • ArrayList
  • SinglyLinkedList
  • DoublyLinkedList
  • TreeMap
  • TreeSet
  • ArrayStack
  • LinkedListStack
  • BinaryHeap
  • RedBlackTree

Excluded unordered containers:

  • HashSet
  • HashMap

Two different types of iterators:

  • IteratorWithIndex (for containers whose elements are index by a numeric position)
  • IteratorWithKey (for containers whose elements are of type key value pairs)

Example:

// IteratorWithIndex
it := list.Iterator()
for it.Next() { // moves iterator to next, returns true if there was a next
    index := it.Index() // does not mutate iterator's state (type int)
    value := it.Value() // does not mutate iterator's state (type interface{})
    ...
}
// IteratorWithKey
it := map.Iterator()
for it.Next() { // moves iterator to next, returns true if there was a next
    key := it.Key() // does not mutate iterator's state (type interface{})
    value := it.Value() // does not mutate iterator's state (type interface{})
    ...
}

Enumerable

Added enumerable to:

  • ArrayList
  • SinglyLinkedList
  • DoublyLinkedList
  • TreeMap
  • TreeSet
  • ArrayStack

Two different types of enumerables:

  • EnumerableWithIndex (for containers whose elements are index by a numeric position)
  • EnumerableWithKey (for containers whose elements are of type key value pairs)

Enumerable is Ruby inspired and supports for now the following functions:

  • Each (iterate over elements of a container)
  • Map (creates new container by mapping each element into a new element)
  • Select (creates a new container by selecting only elements based on a criteria)
  • Any (returns true if any of the elements satisfy the criteria)
  • All (returns true if all of the elements satisfy the criteria)
  • Find (find the first element (index/key and value) in a container satisfying the criteria otherwise returns -1/nil, nil)

Example EnumerableWithIndex:

package main

import (
    "fmt"
    "github.com/emirpasic/gods/sets/treeset"
)

func printSet(txt string, set *treeset.Set) {
    fmt.Print(txt, "[ ")
    set.Each(func(index int, value interface{}) {
        fmt.Print(value, " ")
    })
    fmt.Println("]")
}

func main() {
    set := treeset.NewWithIntComparator()
    set.Add(2, 3, 4, 2, 5, 6, 7, 8)
    printSet("Initial", set) // [ 2 3 4 5 6 7 8 ]

    even := set.Select(func(index int, value interface{}) bool {
        return value.(int)%2 == 0
    })
    printSet("Even numbers", even) // [ 2 4 6 8 ]

    foundIndex, foundValue := set.Find(func(index int, value interface{}) bool {
        return value.(int)%2 == 0 && value.(int)%3 == 0
    })
    if foundIndex != -1 {
        fmt.Println("Number divisible by 2 and 3 found is", foundValue, "at index", foundIndex) // value: 6, index: 4
    }

    square := set.Map(func(index int, value interface{}) interface{} {
        return value.(int) * value.(int)
    })
    printSet("Numbers squared", square) // [ 4 9 16 25 36 49 64 ]

    bigger := set.Any(func(index int, value interface{}) bool {
        return value.(int) > 5
    })
    fmt.Println("Set contains a number bigger than 5 is ", bigger) // true

    positive := set.All(func(index int, value interface{}) bool {
        return value.(int) > 0
    })
    fmt.Println("All numbers are positive is", positive) // true

    evenNumbersSquared := set.Select(func(index int, value interface{}) bool {
        return value.(int)%2 == 0
    }).Map(func(index int, value interface{}) interface{} {
        return value.(int) * value.(int)
    })
    printSet("Chaining", evenNumbersSquared) // [ 4 16 36 64 ]
}

Example EnumerableWithKey:

package main

import (
    "fmt"
    "github.com/emirpasic/gods/maps/treemap"
)

func printMap(txt string, m *treemap.Map) {
    fmt.Print(txt, " { ")
    m.Each(func(key interface{}, value interface{}) {
        fmt.Print(key, ":", value, " ")
    })
    fmt.Println("}")
}

func main() {
    m := treemap.NewWithStringComparator()
    m.Put("g", 7)
    m.Put("f", 6)
    m.Put("e", 5)
    m.Put("d", 4)
    m.Put("c", 3)
    m.Put("b", 2)
    m.Put("a", 1)
    printMap("Initial", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 }

    even := m.Select(func(key interface{}, value interface{}) bool {
        return value.(int)%2 == 0
    })
    printMap("Elements with even values", even) // { b:2 d:4 f:6 }

    foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool {
        return value.(int)%2 == 0 && value.(int)%3 == 0
    })
    if foundKey != nil {
        fmt.Println("Element with value divisible by 2 and 3 found is", foundValue, "with key", foundKey) // value: 6, index: 4
    }

    square := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
        return key.(string) + key.(string), value.(int) * value.(int)
    })
    printMap("Elements' values squared and letters duplicated", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 }

    bigger := m.Any(func(key interface{}, value interface{}) bool {
        return value.(int) > 5
    })
    fmt.Println("Map contains element whose value is bigger than 5 is", bigger) // true

    positive := m.All(func(key interface{}, value interface{}) bool {
        return value.(int) > 0
    })
    fmt.Println("All map's elements have positive values is", positive) // true

    evenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool {
        return value.(int)%2 == 0
    }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) {
        return key, value.(int) * value.(int)
    })
    printMap("Chaining", evenNumbersSquared) // { b:4 d:16 f:36 }
}
  • Tests (100% Complete)
  • Documentation (100% Complete)
  • Examples (100% Complete)
Closes #8 # Iterator Added stateful iterator to all ordered containers: - ArrayList - SinglyLinkedList - DoublyLinkedList - TreeMap - TreeSet - ArrayStack - LinkedListStack - BinaryHeap - RedBlackTree Excluded unordered containers: - HashSet - HashMap Two different types of iterators: - IteratorWithIndex (for containers whose elements are index by a numeric position) - IteratorWithKey (for containers whose elements are of type key value pairs) Example: ``` go // IteratorWithIndex it := list.Iterator() for it.Next() { // moves iterator to next, returns true if there was a next index := it.Index() // does not mutate iterator's state (type int) value := it.Value() // does not mutate iterator's state (type interface{}) ... } // IteratorWithKey it := map.Iterator() for it.Next() { // moves iterator to next, returns true if there was a next key := it.Key() // does not mutate iterator's state (type interface{}) value := it.Value() // does not mutate iterator's state (type interface{}) ... } ``` # Enumerable Added enumerable to: - ArrayList - SinglyLinkedList - DoublyLinkedList - TreeMap - TreeSet - ArrayStack Two different types of enumerables: - EnumerableWithIndex (for containers whose elements are index by a numeric position) - EnumerableWithKey (for containers whose elements are of type key value pairs) Enumerable is Ruby inspired and supports for now the following functions: - Each (iterate over elements of a container) - Map (creates new container by mapping each element into a new element) - Select (creates a new container by selecting only elements based on a criteria) - Any (returns true if any of the elements satisfy the criteria) - All (returns true if all of the elements satisfy the criteria) - Find (find the first element (index/key and value) in a container satisfying the criteria otherwise returns -1/nil, nil) Example EnumerableWithIndex: ``` go package main import ( "fmt" "github.com/emirpasic/gods/sets/treeset" ) func printSet(txt string, set *treeset.Set) { fmt.Print(txt, "[ ") set.Each(func(index int, value interface{}) { fmt.Print(value, " ") }) fmt.Println("]") } func main() { set := treeset.NewWithIntComparator() set.Add(2, 3, 4, 2, 5, 6, 7, 8) printSet("Initial", set) // [ 2 3 4 5 6 7 8 ] even := set.Select(func(index int, value interface{}) bool { return value.(int)%2 == 0 }) printSet("Even numbers", even) // [ 2 4 6 8 ] foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { return value.(int)%2 == 0 && value.(int)%3 == 0 }) if foundIndex != -1 { fmt.Println("Number divisible by 2 and 3 found is", foundValue, "at index", foundIndex) // value: 6, index: 4 } square := set.Map(func(index int, value interface{}) interface{} { return value.(int) * value.(int) }) printSet("Numbers squared", square) // [ 4 9 16 25 36 49 64 ] bigger := set.Any(func(index int, value interface{}) bool { return value.(int) > 5 }) fmt.Println("Set contains a number bigger than 5 is ", bigger) // true positive := set.All(func(index int, value interface{}) bool { return value.(int) > 0 }) fmt.Println("All numbers are positive is", positive) // true evenNumbersSquared := set.Select(func(index int, value interface{}) bool { return value.(int)%2 == 0 }).Map(func(index int, value interface{}) interface{} { return value.(int) * value.(int) }) printSet("Chaining", evenNumbersSquared) // [ 4 16 36 64 ] } ``` Example EnumerableWithKey: ``` go package main import ( "fmt" "github.com/emirpasic/gods/maps/treemap" ) func printMap(txt string, m *treemap.Map) { fmt.Print(txt, " { ") m.Each(func(key interface{}, value interface{}) { fmt.Print(key, ":", value, " ") }) fmt.Println("}") } func main() { m := treemap.NewWithStringComparator() m.Put("g", 7) m.Put("f", 6) m.Put("e", 5) m.Put("d", 4) m.Put("c", 3) m.Put("b", 2) m.Put("a", 1) printMap("Initial", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 } even := m.Select(func(key interface{}, value interface{}) bool { return value.(int)%2 == 0 }) printMap("Elements with even values", even) // { b:2 d:4 f:6 } foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { return value.(int)%2 == 0 && value.(int)%3 == 0 }) if foundKey != nil { fmt.Println("Element with value divisible by 2 and 3 found is", foundValue, "with key", foundKey) // value: 6, index: 4 } square := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) { return key.(string) + key.(string), value.(int) * value.(int) }) printMap("Elements' values squared and letters duplicated", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 } bigger := m.Any(func(key interface{}, value interface{}) bool { return value.(int) > 5 }) fmt.Println("Map contains element whose value is bigger than 5 is", bigger) // true positive := m.All(func(key interface{}, value interface{}) bool { return value.(int) > 0 }) fmt.Println("All map's elements have positive values is", positive) // true evenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool { return value.(int)%2 == 0 }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { return key, value.(int) * value.(int) }) printMap("Chaining", evenNumbersSquared) // { b:4 d:16 f:36 } } ``` - Tests (100% Complete) - Documentation (100% Complete) - Examples (100% Complete)
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
golibs/gms-gods!12
No description provided.