From 04706e8d03ffb3229c2e9fdd972c4d74a4604791 Mon Sep 17 00:00:00 2001 From: Emir Pasic Date: Tue, 21 Jun 2016 05:31:00 +0200 Subject: [PATCH] - start on enumarables (arraylist implemented) --- enumerable/enumerable.go | 57 ++++++++++++++++++++++++++++++++++++ lists/arraylist/arraylist.go | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 enumerable/enumerable.go diff --git a/enumerable/enumerable.go b/enumerable/enumerable.go new file mode 100644 index 0000000..9e76e43 --- /dev/null +++ b/enumerable/enumerable.go @@ -0,0 +1,57 @@ +/* +Copyright (c) 2015, Emir Pasic +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Enumerable functions for ordered containers. +// Ruby's enumerable inspired package. + +package enumerable + +import "github.com/emirpasic/gods/containers" + +type Interface interface { + // Calls the given function once for each element, passing that element's index(key) and value. + Each(func(index interface{}, value interface{})) + + // Invokes the given function once for each element and returns a + // container containing the values returned by the given function. + Map(func(index interface{}, value interface{}) interface{}) containers.Interface + + // Returns a new container containing all elements for which the given function returns a true value. + Select(func(index interface{}, value interface{}) bool) containers.Interface + + // Passes each element of the collection to the given function and + // returns true if the function ever returns true for any element. + Any(func(index interface{}, value interface{}) bool) bool + + // Passes each element of the collection to the given function and + // returns true if the function returns true for all elements. + All(func(index interface{}, value interface{}) bool) bool + + // Passes each element of the collection to the given function and returns + // the first for which the function is true or nil,nil otherwise if no element + // matches the criteria. + Find(func(index interface{}, value interface{}) bool) (index interface{}, value interface{}) +} diff --git a/lists/arraylist/arraylist.go b/lists/arraylist/arraylist.go index 278f153..60d25f9 100644 --- a/lists/arraylist/arraylist.go +++ b/lists/arraylist/arraylist.go @@ -32,6 +32,8 @@ package arraylist import ( "fmt" + "github.com/emirpasic/gods/containers" + "github.com/emirpasic/gods/enumerable" "github.com/emirpasic/gods/lists" "github.com/emirpasic/gods/utils" "strings" @@ -39,6 +41,7 @@ import ( func assertInterfaceImplementation() { var _ lists.Interface = (*List)(nil) + var _ enumerable.Interface = (*List)(nil) } type List struct { @@ -175,6 +178,57 @@ func (list *List) Insert(index int, values ...interface{}) { } } +func (list *List) Each(f func(index interface{}, value interface{})) { + for i := 0; i < list.size; i++ { + f(i, list.elements[i]) + } +} + +func (list *List) Map(f func(index interface{}, value interface{}) interface{}) containers.Interface { + newList := &List{} + for i := 0; i < list.size; i++ { + newList.Add(f(i, list.elements[i])) + } + return newList +} + +func (list *List) Select(f func(index interface{}, value interface{}) bool) containers.Interface { + newList := &List{} + for i := 0; i < list.size; i++ { + if f(i, list.elements[i]) { + newList.Add(list.elements[i]) + } + } + return newList +} + +func (list *List) Any(f func(index interface{}, value interface{}) bool) bool { + for i := 0; i < list.size; i++ { + if f(i, list.elements[i]) { + return true + } + } + return false +} + +func (list *List) All(f func(index interface{}, value interface{}) bool) bool { + for i := 0; i < list.size; i++ { + if !f(i, list.elements[i]) { + return false + } + } + return true +} + +func (list *List) Find(f func(index interface{}, value interface{}) bool) (index interface{}, value interface{}) { + for i := 0; i < list.size; i++ { + if f(i, list.elements[i]) { + return i, list.elements[i] + } + } + return nil, nil +} + func (list *List) String() string { str := "ArrayList\n" values := []string{}