collection

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2017 License: MIT Imports: 6 Imported by: 59

README

collection

GoDoc Build Status Go Report Card

Usage

Querying Collections

Inspired by .NET's Linq, querying data structures used in this library is a snap! Build Go pipelines quickly and easily which will apply lambdas as they query your data structures.

Slices

Converting between slices and a queryable structure is as trivial as it should be.

subject := []interface{}{"a", "b", "c"}

for entry := range collection.AsEnumerator(subject...) {
    fmt.Println(entry)
}
// Output:
// a
// b
// c

Where
subject := collection.AsEnumerator(1, 2, 3, 4, 5, 6)
subject = subject.Where(func(num interface{}) bool{
    return num.(int) > 3
})
for entry := range subject {
    fmt.Println(entry)
}
// Output:
// 4
// 5
// 6
Select
subject := collection.AsEnumerator(1, 2, 3, 4, 5, 6)
subject = subject.Select(func(num interface{}) interface{}{
    return num.(int) + 10
}).Take(3)
for entry := range subject {
    fmt.Println(entry)
}
// Output:
// 11
// 12
// 13

Queues

Creating a Queue
subject := collection.NewQueue(1, 2, 3, 5, 8, 13)
selected := subject.Enumerate().Skip(3).Take(3)
for entry := range selected {
    fmt.Println(entry)
}
// Output:
// 5
// 8
// 13
Checking if a Queue is empty
populated := collection.NewQueue(1, 2, 3, 5, 8, 13)
notPopulated := collection.NewQueue()
fmt.Println(populated.IsEmpty())
fmt.Println(notPopulated.IsEmpty())
// Output:
// false
// true

Versioning

This library will conform to strict semantic versions as defined by semver.org's v2 specification.

Contributing

I accept contributions! To ensure glide users and go get users retreive the same commit, please submit PRs to the 'dev' branch. Remember to add tests!

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrUnexpectedType = errors.New("value was of an unexpected type")
)

A collection of errors that may be thrown by functions in this file.

Functions

func Any added in v0.2.0

func Any(iterator Enumerable) bool

Any tests an Enumerable to see if there are any elements present.

func Anyp added in v0.2.0

func Anyp(iterator Enumerable, p Predicate) bool

Anyp tests an Enumerable to see if there are any elements present that meet a criteria.

func Count added in v0.2.0

func Count(iter Enumerable, p Predicate) int

Count iterates over a list and keeps a running tally of the number of elements satisfy a predicate.

func CountAll added in v0.2.0

func CountAll(iter Enumerable) int

CountAll iterates over a list and keeps a running tally of how many it's seen.

func ElementAt added in v0.2.0

func ElementAt(iter Enumerable, n uint) interface{}

ElementAt retreives an item at a particular position in an Enumerator.

func Identity added in v0.2.0

func Identity(value interface{}) interface{}

Identity is a trivial Transform which applies no operation on the value.

func Last added in v0.2.0

func Last(iter Enumerable) interface{}

Last retreives the item logically behind all other elements in the list.

func Single added in v0.2.0

func Single(iter Enumerable) (interface{}, error)

Single retreives the only element from a list, or returns nil and an error.

func ToSlice added in v0.2.0

func ToSlice(iter Enumerable) []interface{}

ToSlice places all iterated over values in a Slice for easy consumption.

func UCount added in v0.2.0

func UCount(iter Enumerable, p Predicate) uint

UCount iterates over a list and keeps a running tally of the number of elements satisfy a predicate.

func UCountAll added in v0.2.0

func UCountAll(iter Enumerable) uint

UCountAll iterates over a list and keeps a running tally of how many it's seen.

Types

type Comparator

type Comparator func(a, b interface{}) (int, error)

Comparator is a function which evaluates two values to determine their relation to one another. - Zero is returned when `a` and `b` are equal. - Positive numbers are returned when `a` is greater than `b`. - Negative numbers are returned when `a` is less than `b`.

type Enumerable

type Enumerable interface {
	Enumerate() Enumerator
}

Enumerable offers a means of easily converting into a channel. It is most useful for types where mutability is not in question.

func AsEnumerable added in v0.2.0

func AsEnumerable(entries ...interface{}) Enumerable

AsEnumerable allows for easy conversion of a slice to a re-usable Enumerable object.

type Enumerator

type Enumerator <-chan interface{}

Enumerator exposes a new syntax for querying familiar data structures.

func AsEnumerator

func AsEnumerator(entries ...interface{}) Enumerator

AsEnumerator allows for easy conversion to an Enumerator from a slice.

func Merge

func Merge(channels ...Enumerator) Enumerator

Merge takes the results as it receives them from several channels and directs them into a single channel.

Example
a := AsEnumerator(1, 2, 4)
b := AsEnumerator(8, 16, 32)
c := Merge(a, b)
sum := 0
for x := range c {
	sum += x.(int)
}
fmt.Println(sum)
Output:

63

func (Enumerator) All

func (iter Enumerator) All(p Predicate) bool

All tests whether or not all items present meet a criteria.

func (Enumerator) Any

func (iter Enumerator) Any() bool

Any tests an Enumerator to see if there are any elements present.

Example
empty := AsEnumerator()
if empty.Any() {
	fmt.Println("Empty had some")
} else {
	fmt.Println("Empty had none")
}

populated := AsEnumerator("str1")
if populated.Any() {
	fmt.Println("Populated had some")
} else {
	fmt.Println("Populated had none")
}
Output:

Empty had none
Populated had some

func (Enumerator) Anyp

func (iter Enumerator) Anyp(p Predicate) bool

Anyp tests an Enumerator to see if there are any elements present that meet a criteria.

func (Enumerator) Cache added in v0.2.0

func (iter Enumerator) Cache() Enumerable

Cache stores the results of an Enumerator so the results can be enumerated over repeatedly.

func (Enumerator) Count

func (iter Enumerator) Count(p Predicate) int

Count iterates over a list and keeps a running tally of the number of elements satisfy a predicate.

Example
subject := AsEnumerator("str1", "str1", "str2")
count1 := subject.Count(func(a interface{}) bool {
	return a == "str1"
})
fmt.Println(count1)
Output:

2

func (Enumerator) CountAll

func (iter Enumerator) CountAll() int

CountAll iterates over a list and keeps a running tally of how many it's seen.

Example
subject := AsEnumerator('a', 'b', 'c', 'd', 'e')
fmt.Println(subject.CountAll())
// Ouput: 5

func (Enumerator) ElementAt

func (iter Enumerator) ElementAt(n uint) interface{}

ElementAt retreives an item at a particular position in an Enumerator.

Example
subject := AsEnumerator(1, 2, 3, 5, 8)
fmt.Print(subject.ElementAt(2))
Output:

3

func (Enumerator) Last

func (iter Enumerator) Last() (retval interface{})

Last retreives the item logically behind all other elements in the list.

Example
subject := AsEnumerator(1, 2, 3)
fmt.Print(subject.Last())
Output:

3

func (Enumerator) Merge

func (iter Enumerator) Merge(items ...Enumerator) Enumerator

Merge combines the results from this Enumerator with that of several others.

Example
a := AsEnumerator(1, 2, 4)
b := AsEnumerator(8, 16, 32)
c := a.Merge(b)
sum := 0
for x := range c {
	sum += x.(int)
}
fmt.Println(sum)
Output:

63

func (Enumerator) ParallelSelect added in v0.2.0

func (iter Enumerator) ParallelSelect(operation Transform) Enumerator

ParallelSelect spreads an expensive Transform across several go-routines, results are not likely to be returned in the same order.

Example
a := AsEnumerator(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)

multiplied := a.ParallelSelect(func(num interface{}) interface{} {
	time.Sleep(50 * time.Millisecond)
	return num.(int) * 5
})

sum := 0
for entry := range multiplied {
	sum = sum + entry.(int)
}
fmt.Print(sum)
Output:

525

func (Enumerator) Reverse

func (iter Enumerator) Reverse() Enumerator

Reverse returns items in the opposite order it encountered them in.

Example
a := AsEnumerator(1, 2, 3)
fmt.Println(a.Reverse().ToSlice())
Output:

[3 2 1]

func (Enumerator) Select

func (iter Enumerator) Select(transform Transform) Enumerator

Select iterates over a list and returns a transformed item.

Example
subject := AsEnumerator('a', 'b', 'c')
const offset = 'a' - 1
results := subject.Select(func(a interface{}) interface{} {
	return a.(rune) - offset
})

fmt.Println(results.ToSlice())
Output:

[1 2 3]

func (Enumerator) SelectMany added in v0.2.0

func (iter Enumerator) SelectMany(lister func(interface{}) Enumerator) Enumerator

SelectMany allows for flattening of data structures.

Example
type BrewHouse struct {
	Name  string
	Beers []interface{}
}

breweries := AsEnumerator(
	BrewHouse{
		"Mac & Jacks",
		[]interface{}{
			"African Amber",
			"Ibis IPA",
		},
	},
	BrewHouse{
		"Post Doc",
		[]interface{}{
			"Prereq Pale",
		},
	},
	BrewHouse{
		"Resonate",
		[]interface{}{
			"Comfortably Numb IPA",
			"Lithium Altbier",
		},
	},
	BrewHouse{
		"Triplehorn",
		[]interface{}{
			"Samson",
			"Pepper Belly",
		},
	},
)

beers := breweries.SelectMany(func(brewer interface{}) Enumerator {
	return AsEnumerator(brewer.(BrewHouse).Beers...)
})

for beer := range beers {
	fmt.Println(beer)
}
Output:

African Amber
Ibis IPA
Prereq Pale
Comfortably Numb IPA
Lithium Altbier
Samson
Pepper Belly

func (Enumerator) Single

func (iter Enumerator) Single() (retval interface{}, err error)

Single retreives the only element from a list, or returns nil and an error.

Example
a := AsEnumerator(1, 2, 3)
b := AsEnumerator(4)
if val, err := a.Single(); err == nil {
	fmt.Println(val)
}

if val, err := b.Single(); err == nil {
	fmt.Println(val)
}
Output:

4

func (Enumerator) Skip

func (iter Enumerator) Skip(n uint) Enumerator

Skip retreives all elements after the first 'n' elements.

Example
subject := AsEnumerator(1, 2, 3, 4, 5, 6, 7)
subject = subject.Skip(5)
for entry := range subject {
	fmt.Println(entry)
}
Output:

6
7

func (Enumerator) Split

func (iter Enumerator) Split(operation Transform) (Enumerator, Enumerator)

Split creates two Enumerators, each will be a subset of the original Enumerator and will have distinct populations from one another.

Example
a := AsEnumerator(1, 2, 4, 8, 16)
left, right := a.Split(Identity)

var wg sync.WaitGroup
wg.Add(2)

leftSum := 0
go func() {
	for x := range left {
		leftSum += x.(int)
	}
	wg.Done()
}()

rightSum := 0
go func() {
	for y := range right {
		rightSum += y.(int)
	}
	wg.Done()
}()
wg.Wait()

fmt.Print(leftSum + rightSum)
Output:

31

func (Enumerator) SplitN added in v0.2.0

func (iter Enumerator) SplitN(operation Transform, n uint) []Enumerator

SplitN creates N Enumerators, each will be a subset of the original Enumerator and will have distinct populations from one another.

Example
rawNums := make([]interface{}, 1000, 1000)
for i := 0; i < len(rawNums); i++ {
	rawNums[i] = i + 1
}
nums := AsEnumerator(rawNums...)

workers := nums.SplitN(func(num interface{}) interface{} {
	return num.(int) * 3
}, 8)

sum := 0
results := Merge(workers...)
for num := range results {
	sum += num.(int)
}
fmt.Println(sum)
Output:

1501500

func (Enumerator) Take

func (iter Enumerator) Take(n uint) Enumerator

Take retreives just the first 'n' elements from an Enumerator

Example
subject := AsEnumerator(1, 2, 3, 4, 5, 6)
subject = subject.Skip(2).Take(3)
for entry := range subject {
	fmt.Println(entry)
}
Output:

3
4
5

func (Enumerator) TakeWhile

func (iter Enumerator) TakeWhile(criteria func(interface{}, uint) bool) Enumerator

TakeWhile continues returning items as long as 'criteria' holds true.

Example
subject := AsEnumerator(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
subject = subject.TakeWhile(func(x interface{}, n uint) bool {
	return x.(int) < 6
})
for entry := range subject {
	fmt.Println(entry)
}
Output:

1
2
3
4
5

func (Enumerator) Tee

func (iter Enumerator) Tee() (Enumerator, Enumerator)

Tee creates two Enumerators which will have identical contents as one another.

Example
base := AsEnumerator(1, 2, 4)
left, right := base.Tee()
var wg sync.WaitGroup
wg.Add(2)

product := 1
go func() {
	for x := range left {
		product *= x.(int)
	}
	wg.Done()
}()

sum := 0
go func() {
	for x := range right {
		sum += x.(int)
	}
	wg.Done()
}()

wg.Wait()

fmt.Printf("Sum: %d\n", sum)
fmt.Printf("Product: %d\n", product)
Output:

Sum: 7
Product: 8

func (Enumerator) ToSlice

func (iter Enumerator) ToSlice() []interface{}

ToSlice places all iterated over values in a Slice for easy consumption.

func (Enumerator) UCount

func (iter Enumerator) UCount(p Predicate) uint

UCount iterates over a list and keeps a running tally of the number of elements satisfy a predicate.

Example
subject := AsEnumerator("str1", "str1", "str2")
count1 := subject.UCount(func(a interface{}) bool {
	return a == "str1"
})
fmt.Println(count1)
Output:

2

func (Enumerator) UCountAll

func (iter Enumerator) UCountAll() uint

UCountAll iterates over a list and keeps a running tally of how many it's seen.

Example
subject := AsEnumerator('a', 2, "str1")
fmt.Println(subject.UCountAll())
Output:

3

func (Enumerator) Where

func (iter Enumerator) Where(predicate Predicate) Enumerator

Where iterates over a list and returns only the elements that satisfy a predicate.

Example
subject := AsEnumerator(1, 2, 3, 5, 8, 13, 21, 34)
results := subject.Where(func(a interface{}) bool { return a.(int) > 8 }).ToSlice()
fmt.Println(results)
Output:

[13 21 34]

type LinkedList

type LinkedList struct {
	// contains filtered or unexported fields
}

LinkedList encapsulates a list where each entry is aware of only the next entry in the list.

func NewLinkedList

func NewLinkedList(entries ...interface{}) *LinkedList

NewLinkedList instantiates a new LinkedList with the entries provided.

Example
subject1 := NewLinkedList('a', 'b', 'c', 'd', 'e')
fmt.Println(subject1.Length())

slice := []interface{}{1, 2, 3, 4, 5, 6}
subject2 := NewLinkedList(slice...)
fmt.Println(subject2.Length())
Output:

5
6

func (*LinkedList) AddBack

func (list *LinkedList) AddBack(entry interface{})

AddBack creates an entry in the LinkedList that is logically at the back of the list.

Example
subject := NewLinkedList(2, 3, 5)
subject.AddBack(8)
result, _ := subject.PeekBack()
fmt.Println(result)
fmt.Println(subject.Length())
Output:

8
4

func (*LinkedList) AddFront

func (list *LinkedList) AddFront(entry interface{})

AddFront creates an entry in the LinkedList that is logically at the front of the list.

Example
subject := NewLinkedList(2, 3)
subject.AddFront(1)
result, _ := subject.PeekFront()
fmt.Println(result)
Output:

1

func (*LinkedList) Enumerate

func (list *LinkedList) Enumerate() Enumerator

Enumerate creates a new instance of Enumerable which can be executed on.

Example
subject := NewLinkedList(2, 3, 5, 8)
results := subject.Enumerate().Select(func(a interface{}) interface{} {
	return -1 * a.(int)
})
for entry := range results {
	fmt.Println(entry)
}
Output:

-2
-3
-5
-8

func (*LinkedList) Get

func (list *LinkedList) Get(pos uint) (interface{}, bool)

Get finds the value from the LinkedList. pos is expressed as a zero-based index begining from the 'front' of the list.

Example
subject := NewLinkedList(2, 3, 5, 8)
val, _ := subject.Get(2)
fmt.Println(val)
Output:

5

func (*LinkedList) IsEmpty

func (list *LinkedList) IsEmpty() bool

IsEmpty tests the list to determine if it is populate or not.

func (*LinkedList) Length

func (list *LinkedList) Length() uint

Length returns the number of elements present in the LinkedList.

func (*LinkedList) PeekBack

func (list *LinkedList) PeekBack() (interface{}, bool)

PeekBack returns the entry logicall stored at the back of the list without removing it.

func (*LinkedList) PeekFront

func (list *LinkedList) PeekFront() (interface{}, bool)

PeekFront returns the entry logically stored at the front of this list without removing it.

func (*LinkedList) RemoveBack

func (list *LinkedList) RemoveBack() (interface{}, bool)

RemoveBack returns the entry logically stored at the back of this list and removes it.

func (*LinkedList) RemoveFront

func (list *LinkedList) RemoveFront() (interface{}, bool)

RemoveFront returns the entry logically stored at the front of this list and removes it.

func (*LinkedList) Sort

func (list *LinkedList) Sort(comparator Comparator) error

Sort rearranges the positions of the entries in this list so that they are ascending.

Example
// Sorti sorts into ascending order, this example demonstrates sorting
// into descending order.
subject := NewLinkedList(2, 4, 3, 5, 7, 7)
subject.Sort(func(a, b interface{}) (int, error) {
	castA, ok := a.(int)
	if !ok {
		return 0, ErrUnexpectedType
	}
	castB, ok := b.(int)
	if !ok {
		return 0, ErrUnexpectedType
	}

	return castB - castA, nil
})
fmt.Println(subject)
Output:

[7 7 5 4 3 2]

func (*LinkedList) Sorta

func (list *LinkedList) Sorta() error

Sorta rearranges the position of string entries in this list so that they are ascending.

Example
subject := NewLinkedList("charlie", "alfa", "bravo", "delta")
subject.Sorta()
for _, entry := range subject.ToSlice() {
	fmt.Println(entry.(string))
}
Output:

alfa
bravo
charlie
delta

func (*LinkedList) Sorti

func (list *LinkedList) Sorti() (err error)

Sorti rearranges the position of integer entries in this list so that they are ascending.

Example
subject := NewLinkedList(7, 3, 2, 2, 3, 6)
subject.Sorti()
fmt.Println(subject)
Output:

[2 2 3 3 6 7]

func (*LinkedList) String

func (list *LinkedList) String() string

String prints upto the first fifteen elements of the list in string format.

Example
subject1 := NewLinkedList()
for i := 0; i < 20; i++ {
	subject1.AddBack(i)
}
fmt.Println(subject1)

subject2 := NewLinkedList(1, 2, 3)
fmt.Println(subject2)
Output:

[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...]
[1 2 3]

func (*LinkedList) Swap

func (list *LinkedList) Swap(x, y uint) error

Swap switches the positions in which two values are stored in this list. x and y represent the indexes of the items that should be swapped.

Example
subject := NewLinkedList(2, 3, 5, 8, 13)
subject.Swap(1, 3)
fmt.Println(subject)
Output:

[2 8 5 3 13]

func (*LinkedList) ToSlice

func (list *LinkedList) ToSlice() []interface{}

ToSlice converts the contents of the LinkedList into a slice.

type List

type List struct {
	// contains filtered or unexported fields
}

List is a dynamically sized list akin to List in the .NET world, ArrayList in the Java world, or vector in the C++ world.

func NewList

func NewList(entries ...interface{}) *List

NewList creates a new list which contains the elements provided.

func (*List) Add

func (l *List) Add(entries ...interface{})

Add appends an entry to the logical end of the List.

func (*List) AddAt

func (l *List) AddAt(pos uint, entries ...interface{})

AddAt injects values beginning at `pos`. If multiple values are provided in `entries` they are placed in the same order they are provided.

Example
subject := NewList(0, 1, 4, 5, 6)
subject.AddAt(2, 2, 3)
fmt.Println(subject)
Output:

[0 1 2 3 4 5 6]

func (*List) Enumerate

func (l *List) Enumerate() Enumerator

Enumerate lists each element present in the collection

func (*List) Get

func (l *List) Get(pos uint) (interface{}, bool)

Get retreives the value stored in a particular position of the list. If no item exists at the given position, the second parameter will be returned as false.

func (*List) IsEmpty

func (l *List) IsEmpty() bool

IsEmpty tests to see if this List has any elements present.

func (*List) Length

func (l *List) Length() uint

Length returns the number of elements in the List.

func (*List) Remove

func (l *List) Remove(pos uint) (interface{}, bool)

Remove retreives a value from this List and shifts all other values.

func (*List) Set

func (l *List) Set(pos uint, val interface{}) bool

Set updates the value stored at a given position in the List.

func (*List) String

func (l *List) String() string

String generates a textual representation of the List for the sake of debugging.

func (*List) Swap

func (l *List) Swap(x, y uint) bool

Swap switches the values that are stored at positions `x` and `y`

type Predicate

type Predicate func(interface{}) bool

Predicate defines an interface for funcs that make some logical test.

type Queue

type Queue struct {
	// contains filtered or unexported fields
}

Queue implements a basic FIFO structure.

func NewQueue

func NewQueue(entries ...interface{}) *Queue

NewQueue instantiates a new FIFO structure.

Example
empty := NewQueue()
fmt.Println(empty.Length())

populated := NewQueue(1, 2, 3, 5, 8, 13)
fmt.Println(populated.Length())
Output:

0
6

func (*Queue) Add

func (q *Queue) Add(entry interface{})

Add places an item at the back of the Queue.

Example
subject := &Queue{}
subject.Add(1)
subject.Add(2)
res, _ := subject.Peek()
fmt.Println(res)
Output:

1

func (*Queue) Enumerate added in v0.2.0

func (q *Queue) Enumerate() Enumerator

Enumerate peeks at each element of this queue without mutating it.

func (*Queue) IsEmpty

func (q *Queue) IsEmpty() bool

IsEmpty tests the Queue to determine if it is populate or not.

Example
empty := NewQueue()
fmt.Println(empty.IsEmpty())

populated := NewQueue(1, 2, 3, 5, 8, 13)
fmt.Println(populated.IsEmpty())
Output:

true
false

func (*Queue) Length

func (q *Queue) Length() uint

Length returns the number of items in the Queue.

func (*Queue) Next

func (q *Queue) Next() (interface{}, bool)

Next removes and returns the next item in the Queue.

Example
subject := NewQueue(1, 2, 3, 5, 8, 13)
for !subject.IsEmpty() {
	val, _ := subject.Next()
	fmt.Println(val)
}
Output:

1
2
3
5
8
13

func (*Queue) Peek

func (q *Queue) Peek() (interface{}, bool)

Peek returns the next item in the Queue without removing it.

func (*Queue) ToSlice

func (q *Queue) ToSlice() []interface{}

ToSlice converts a Queue into a slice.

type Stack

type Stack struct {
	// contains filtered or unexported fields
}

Stack implements a basic FILO structure.

func NewStack

func NewStack(entries ...interface{}) *Stack

NewStack instantiates a new FILO structure.

Example
subject := NewStack(1, 2, 3)
for !subject.IsEmpty() {
	val, _ := subject.Pop()
	fmt.Println(val)
}
Output:

3
2
1

func (*Stack) Enumerate added in v0.2.0

func (stack *Stack) Enumerate() <-chan interface{}

Enumerate peeks at each element in the stack without mutating it.

func (*Stack) IsEmpty

func (stack *Stack) IsEmpty() bool

IsEmpty tests the Stack to determine if it is populate or not.

func (*Stack) Peek

func (stack *Stack) Peek() (interface{}, bool)

Peek returns the entry at the top of the Stack without removing it.

func (*Stack) Pop

func (stack *Stack) Pop() (interface{}, bool)

Pop returns the entry at the top of the Stack then removes it.

func (*Stack) Push

func (stack *Stack) Push(entry interface{})

Push adds an entry to the top of the Stack.

func (*Stack) Size

func (stack *Stack) Size() uint

Size returns the number of entries populating the Stack.

type Transform added in v0.2.0

type Transform func(interface{}) interface{}

Transform defines a function which takes a value, and returns some value based on the original.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL