c3

package module
v0.0.0-...-d4c02af Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2021 License: MIT Imports: 3 Imported by: 1

README

This repository has been archived

Build Status c3

The common container collection a.k.a. c3 for go 1.1.

Introduction

This library provides a few basic container interfaces that are missing in Go in my humble opinion. The slice and map containers are nice, but they don't provide very many convenience methods. This library aims to remedy that.

The code lives at http://github.com/ReSc/c3#c3

You can find the CI builds at http://travis-ci.org/ReSc/c3

The api documentation can be found at http://godoc.org/github.com/ReSc/c3

Code Quality

This library has started its life in october 2013 and is still in beta.

Contributions And Bug Reports

Send pull requests!

If you have a bug to report I would be very grateful If you could submit it as a pull request with a failing test.

Road Map

The interfaces Bag, List, Set, Queue and Stack are complete and every interface has an implementation. I don't plan on adding any more container interfaces for the v1 release. Maybe a SortedList and a generic Tree for v2...

There is work to be done in the tests and benchmarks of the implementations. The query api could use some query operators, and there should be more convenience functions for creating and converting and in conversion from and to slices, maps and channels.

Containers

  • Iterable: A container that provides a way to iterate over its elements
  • Bag: An unordered container.
  • List: An ordered, indexable container.
  • Set: An unordered container that does not allow duplicates, and provides a few basic set operations.
  • Stack: A Last-In First-Out container.
  • Queue: A First-In First-Out container.

Thread And Goroutine Safety

These containers are not goroutine- or thread safe.

There is a basic check for concurrent modification while iterating over a container so you'll at least know when things get corrupted because of concurrent modifications Every mutation of a container increments the container version, and Iterator checks this version on every MoveNext(), and panics if it is not what it expects.

This also means you cannot modify a container while iterating over it.

Example:

// Don't do this!
l := c3.ListOf(1,2,3,4)
for i := l.Iterator(); i.MoveNext(); {
	// vv bug here, cannot modify container while iterating over it! vv
	l.Add(i.Value().(int)*2)
}

Element Types

Because Go does not have generics (yet..) I choose interface{} for the element type. This means there will be casting involved with the use of the containers in c3 but Go's type assertions are nice enough to make it only a minor annoyance.

Quering containers

The c3.NewQuery() function provides an entrypoint for the query api of c3. This api is modelled after the C# Linq api.

Example:

l := c3.ListOf(1, 2, 3, 4)
q := c3.NewQuery(l)
result := q.Where(func(e interface{})) { return e.(int)%2 == 0 }).
            Select(func(e interface{}) interface{} { return e.(int) * 10 }).
			ToList()

As you can see this api would be much nicer if Go had lambda expressions so that you could type

e => e.(int) * 10

instead of

func(e interface{}) interface{} { return e.(int) * 10 }

as an alternative you can define named functions to improve readability

Example:

func isMod2(e interface{}) bool {
	return e.(int)%2 == 0
} 

func times10(e interface{}) interface{} {
	return e.(int)*10
} 

l := c3.ListOf(1, 2, 3, 4)
q := c3.NewQuery(l)
result := q.Where(isMod2).
            Select(times10).
			ToList()	

Documentation

Overview

c3 stands for common containers collection and provides a few simple to use containers.

The containers provided:

  • Iterable: a container that allow iterating over its items.
  • Bag: an unordered container that allows duplicate items.
  • Set: an unordered container that does not allow duplicate items.
  • List: an indexable container.
  • Queue: a fifo container.
  • Stack: a lifo container.

It also provides a query api for those containers that looks like C#'s Linq

The code lives at http://github.com/ReSc/c3#c3

You can find the CI builds at http://travis-ci.org/ReSc/c3

The api documentation can be found at http://godoc.org/github.com/ReSc/c3

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func For

func For(c Iterable, action Action)

For applies the action to each item in the Iterable

func Go

func Go(c Iterable, action Action)

Go applies the action to each item in the Iterable on a separate goroutine using an unbuffered channel

func GoBuffered

func GoBuffered(c Iterable, bufferSize int, action Action)

GoBuffered applies the action to each item in the Iterable on a separate goroutine using a buffered channel

func Sort

func Sort(l List, lesser Lesser)

Sort sorts the list with the given Lesser function

func ToSlice

func ToSlice(c Iterable) []interface{}

ToSlice makes a new slice of the items in an Iterable

Types

type Action

type Action func(item interface{})

Action is invoked for every item in the query result.

type Aggregator

type Aggregator func(item interface{}, aggregate interface{}) (aggregateResult interface{})

Aggregator converts an item and an aggregate into an aggregate result

type Bag

type Bag interface {
	Clearer
	ReadOnlyBag
	// Add adds an item to the container,
	// returns true if the container was modified,
	// false if it was not modified
	Add(item interface{}) bool
	// Delete removes an item from the container,
	// returns true if the container was modified,
	// false if it was not modified
	Delete(item interface{}) bool
}

Bag is an unordered mutable container

func BagOf

func BagOf(items ...interface{}) Bag

BagOf creates a Bag with the given items.

func NewBag

func NewBag() Bag

NewBag creates a new, empty Bag.

func ToBag

func ToBag(c Iterable) Bag

ToBag creates a new Bag of the items in an Iterable

type Clearer

type Clearer interface {
	// Clear removes all items from the container.
	Clear()
}

Clearer provides a method to clear the container.

type Consumable

type Consumable interface {
	Consumer() Consumer
}

Consumable is a container that provides a consuming iterator.

type Consume

type Consume func() (interface{}, bool)

Consume removes and returns the next item in a sequence. Returns the next item and true or nil and false if there are no more items.

type Consumer

type Consumer interface {
	Iterator
}

Consumer is an Iterator that removes items from a container.

func WrapConsumer

func WrapConsumer(c <-chan interface{}) Consumer

WrapConsumer wraps a channel in a consuming Iterator

type Generate

type Generate func() (interface{}, bool)

Generate computes the next item in a sequence. Returns the next item and true or nil and false if there are no more items.

func MakeGenerate

func MakeGenerate(i Iterator) Generate

MakeGenerate converts the Iterator into a Generate function.

type Generator

type Generator func() Generate

Generator creates a new Generate function

func MakeGenerator

func MakeGenerator(items Iterable) Generator

MakeGenerator converts the Iterable into a Generator function.

type Indexable

type Indexable interface {
	// Returns the first item and true,
	// or nil and false if there is no first item
	First() (interface{}, bool)
	// Returns the item at the index and true,
	// or nil and false if the index is out of bounds
	Get(index int) (interface{}, bool)
	// Returns the last item and true,
	// or nil and false if there is no last item
	Last() (interface{}, bool)
	// Returns the first index of the item and true,
	// or -1 and false if there is no such item
	IndexOf(item interface{}) (int, bool)
	// Returns the index of the next item before the offset and true,
	// or -1 and false if there is no such item
	PrevIndexOf(offset int, item interface{}) (int, bool)
	// Returns the index of the next item after the offset and true,
	// or -1 and false if there is no such item
	NextIndexOf(offset int, item interface{}) (int, bool)
	// Returns the last index of the item and true,
	// or -1 and false if there is no such item
	LastIndexOf(item interface{}) (int, bool)
}

Indexable provides methods to get items from a container by index

type Iterable

type Iterable interface {
	// returns a new Iterator positioned at the start of the container.
	Iterator() Iterator
}

Iterable is a container of items that can be iterated over.

func EmptyIterable

func EmptyIterable() Iterable

func IterableOf

func IterableOf(items ...interface{}) Iterable

IterableOf creates an Iterable with the given items.

func MakeIterable

func MakeIterable(g Generator) Iterable

MakeIterable converts the Generator function into an Iterable.

func Range

func Range(start, end int) Iterable

Range creates a range iterable that iterates over the ints from start to end inclusive.

e.g.:

Range(0,9) // returns [0,1,2,3,4,5,6,7,8,9]
Range(9,0) // returns [9,8,7,6,5,4,3,2,1,0]

func Repeat

func Repeat(count int, item interface{}) Iterable

Repeat repeats the item count times.

e.g.:

Repeat(3,42) // returns [42,42,42]

type Iterator

type Iterator interface {
	// Move the iterator to the next item, returns true on succes
	// or false if the are no more item
	MoveNext() bool
	// returns the value at the current iterator position, or nil
	Value() interface{}
}

Iterator provides a way to iterate over a container

Usage:

for i := iterable.Iterator(); i.MoveNext(); {
	value := i.Value()
}

Iterator.Value() only return a valid value if the preceding call to Iterator.MoveNext() returned true

func EmptyIterator

func EmptyIterator() Iterator

func IteratorOf

func IteratorOf(items ...interface{}) Iterator

IteratorOf creates an Iterator with the given items.

func MakeIterator

func MakeIterator(g Generate) Iterator

MakeIterator converts the Generate function into an Iterator.

type Lesser

type Lesser func(a, b interface{}) bool

Lesser compares 2 items, such that a<b:true, false otherwise

type List

type List interface {
	Bag
	Indexable
	// Inserts the item at the given index,
	// returns true if the container was modified,
	// false if it was not modified.
	InsertAt(index int, item interface{}) bool
	// Swaps the 2 items at the given indexes
	Swap(i, j int)
	// Deletes the item at the given index,
	// returns true if the container was modified,
	// false if it was not modified.
	DeleteAt(index int) bool
}

func ListOf

func ListOf(items ...interface{}) List

ListOf creates a List with the given items.

func NewList

func NewList() List

NewList creates a new, empty List.

func ToList

func ToList(c Iterable) List

ToList creates a new List of the items in an Iterable

func WrapList

func WrapList(items []interface{}) List

Wraps a slice in a List interface

type ManySelector

type ManySelector func(interface{}) Iterable

ManySelector converts 1 item into zero or more items

type Peeker

type Peeker interface {
	// Peek returns the next item without removing it from the container.
	Peek() (interface{}, bool)
}

Peeker provides a method to look at the next item without removing it from the container.

type Predicate

type Predicate func(item interface{}) bool

Predicate if a function that returns true if the predicate holds for the item.

type Q

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

The c3 query representation

func NewQuery

func NewQuery(items Iterable) *Q

NewQuery provides a entry point to the c3 query api.

Usage:

list := c3.ListOf(1,2,3)
q := NewQuery(list).
	Where(/* filter function here */).
	Select( /* selector function here */).
	ToList() /* collect the results */

func QueryOf

func QueryOf(items ...interface{}) *Q

QueryOf provides a entry point to the c3 query api.

Usage:

q := c3.QueryOf(1,2,3).
	    Where(/* filter function here */).
	    Select( /* selector function here */).
	    ToList() /* collect the results */

func (*Q) Aggregate

func (q *Q) Aggregate(aggregate interface{}, action Aggregator) interface{}

Aggregate applies the action to every item in the query result and combines them in a single result.

func (*Q) All

func (q *Q) All(predicate Predicate) bool

All returns true if the predicate holds for all results, false otherwise.

func (*Q) Any

func (q *Q) Any() bool

Any returns true if there are results, false if there are not any results.

func (*Q) Append

func (q *Q) Append(items ...interface{}) *Q

Appens appends the items to the query result.

func (*Q) Concat

func (q *Q) Concat(items Iterable) *Q

Concat appends the items to the query result.

func (*Q) Contains

func (q *Q) Contains(item interface{}) bool

Contains returns true if the query results contain the item, false otherwise.

func (*Q) Count

func (q *Q) Count() int

Count counts the number of results.

func (*Q) Distinct

func (q *Q) Distinct() *Q

Distinct filters non-unique items from the query result.

func (*Q) First

func (q *Q) First() (interface{}, bool)

First returns the first query result and true, or nil and false if there are no results.

func (*Q) For

func (q *Q) For(action Action)

For applies the action to every item in the query result.

func (*Q) Go

func (q *Q) Go(action Action)

Go applies the action to every item in the query result on a seperate goroutine using an unbuffered channel.

func (*Q) GoBuffered

func (q *Q) GoBuffered(bufferSize int, action Action)

Go applies the action to every item in the query result on a seperate goroutine using a buffered channel of the supplied size.

func (*Q) Iterator

func (q *Q) Iterator() Iterator

Iterator provides an iterator for the query results.

func (*Q) Last

func (q *Q) Last() (interface{}, bool)

Last returns the last query result and true, or nil and false if there are no results.

func (*Q) Prepend

func (q *Q) Prepend(items ...interface{}) *Q

Prepend prepends the items to the query result.

func (*Q) Run

func (q *Q) Run()

Run runs the query and discards the results.

func (*Q) Select

func (q *Q) Select(selector Selector) *Q

Select uses the selector to create a new result for each item.

func (*Q) SelectMany

func (q *Q) SelectMany(selector ManySelector) *Q

SelectMany uses the selector to create an Iteratable containing zero or more items for each item, and concatenates all the results.

func (*Q) Shuffle

func (q *Q) Shuffle() *Q

Shuffle randomizes the order of the result set.

func (*Q) Skip

func (q *Q) Skip(count int) *Q

Skip skips the first count results and returns all results after that. If there are less results Skip returns an empty result set.

func (*Q) Sort

func (q *Q) Sort(lesser Lesser) *Q

Sort sorts the result set using the lesser function.

func (*Q) Take

func (q *Q) Take(count int) *Q

Take truncates the results after count results have been computed. If there are less results Take returns only the available results.

func (*Q) Tee

func (q *Q) Tee(action Action) *Q

Tee applies the action to every item in the query result and passes every result on to the next query operator.

func (*Q) ToBag

func (q *Q) ToBag() Bag

ToBag puts the query results in a new Bag

func (*Q) ToList

func (q *Q) ToList() List

ToList puts the query results in a new List

func (*Q) ToQueue

func (q *Q) ToQueue() Queue

ToQueue puts the unique query results in a new Queue

func (*Q) ToReadOnlyBag

func (q *Q) ToReadOnlyBag() ReadOnlyBag

ToReadOnlyList puts the query results in a new ReadOnlyList

func (*Q) ToReadOnlyList

func (q *Q) ToReadOnlyList() ReadOnlyList

ToReadOnlyList puts the query results in a new ReadOnlyList

func (*Q) ToSet

func (q *Q) ToSet() Set

ToSet puts the unique query results in a new Set

func (*Q) ToSlice

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

ToSlice puts the query results in a new slice

func (*Q) ToStack

func (q *Q) ToStack() Stack

ToStack puts the unique query results in a new Stack

func (*Q) Where

func (q *Q) Where(filter Predicate) *Q

Filters the items using the filter function. If filter returns true, the item is included in the result, otherwise it is skipped.

type Queue

type Queue interface {
	ReadOnlyBag
	Peeker
	Clearer
	Consumable
	// Appends an item at the tail of the queue,
	// returns true if the queue was modified,
	// false if it was not modified.
	Enqueue(item interface{}) bool
	// Removes an item from the head of the queue,
	// returns the item and true if the queue was modified,
	// or nil and false if it was not modified.
	Dequeue() (interface{}, bool)
}

A simple queuing container.

func NewQueue

func NewQueue() Queue

NewQueue creates a new, empty Queue.

func QueueOf

func QueueOf(items ...interface{}) Queue

QueueOf creates a Queue with the given items.

func ToQueue

func ToQueue(c Iterable) Queue

ToQueue makes a new Queue of the items in an Iterable

type ReadOnlyBag

type ReadOnlyBag interface {
	Iterable
	// Returns the item count
	Len() int
	// Returns true if the item is in the container, false otherwise.
	Contains(item interface{}) bool
}

ReadOnlyBag provides a length and a test for determining if an item is present in a container

func ReadOnlyBagOf

func ReadOnlyBagOf(items ...interface{}) ReadOnlyBag

ReadOnlyBagOf creates a ReadOnlyBag with the given items.

func ToReadOnlyBag

func ToReadOnlyBag(c Iterable) ReadOnlyBag

ToReadOnlyBag creates a new ReadOnlyBag of the items in an Iterable

type ReadOnlyList

type ReadOnlyList interface {
	ReadOnlyBag
	Indexable
}

ReadOnlyList is an indexable readonly list

func ReadOnlyListOf

func ReadOnlyListOf(items ...interface{}) ReadOnlyList

ReadOnlyListOf creates a ReadOnlyList with the given items.

func ToReadOnlyList

func ToReadOnlyList(c Iterable) ReadOnlyList

ToReadOnlyList creates a new ReadOnlyList of the items in an Iterable

type Selector

type Selector func(item interface{}) interface{}

Selector converts an item into another item

type Set

type Set interface {
	Bag
	// Union computes the union of the set.
	// i.e. all items in this set and the other set, without duplicates
	Union(other Set) Set
	// SymmetricDifference computes the symmetric difference of the sets.
	// i.e. all the items that are either in this set,
	// or in the other set, but not in both.
	SymmetricDifference(other Set) Set
	// Difference computes the items that are in this set but not in the other set.
	Difference(other Set) Set
	// Intersection computes the items that are present in both sets.
	Intersection(other Set) Set
}

A set type with basic set operations. See also http://en.wikipedia.org/wiki/Set_theory

func NewSet

func NewSet() Set

NewSet creates a new, empty Set.

func SetOf

func SetOf(items ...interface{}) Set

SetOf creates a new Set containing the unique items.

func ToSet

func ToSet(c Iterable) Set

ToSet makes a new Set of the unique items in an Iterable

type Sorter

type Sorter struct {
	List
	Lesser
}

func (*Sorter) Less

func (s *Sorter) Less(i, j int) bool

func (*Sorter) Sort

func (s *Sorter) Sort()

type Stack

type Stack interface {
	ReadOnlyBag
	Peeker
	Clearer
	Consumable
	// Adds an item at the top of the stack,
	// returns true if the stack was modified,
	// false if it was not modified.
	Push(item interface{}) bool
	// Removes an item from the top of the stack,
	// returns the item and true if the stack was modified,
	// nil and false if it was not modified.
	Pop() (interface{}, bool)
}

A simple stack container

func NewStack

func NewStack() Stack

NewStack creates a new, empty Stack.

func StackOf

func StackOf(items ...interface{}) Stack

StackOf creates a new Stack with the given items.

func ToStack

func ToStack(c Iterable) Stack

ToStack makes a new Stack of the items in an Iterable

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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