godash

package module
v0.0.0-...-7e5f9a5 Latest Latest
Warning

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

Go to latest
Published: Oct 25, 2019 License: MIT Imports: 2 Imported by: 2

README

Godash

Build Status Go Doc

DeepSource

Inspired from Lodash for golang

Why?

  • I did not like most map/reduce implementations that returned an interface{} which had to be typecasted. This library follows the concept of how json.Marshal works. Create an output variable outside the functions and pass a pointer reference to it, so it can be set.
  • This library heavily makes use of reflect package and hence will have an impact on performance. DO NOT USE THIS IN PRODUCTION. This repository is more of a way to learn the reflect package and measure its performance impact.
  • All functions have validations on how mapper function/predicate functions should be written. So even if we lose out on compile time validation, the library still does not panic if it does not know how to handle an argument passed to it.

Available Functions

  1. Map
  2. Filter
  3. Reduce
  4. Any or Some
  5. Find
  6. All or Every

Usages

Map

Map applies a mapper function on each element of an input and sets it in output. For more docs.

func main() {
	input := []int{1, 2, 3, 4, 5}
	var output []int

	godash.Map(input, &output, func(el int) int {
		return el * el
	})

	fmt.Println(output) // prints 1 4 9 16 25
}
type Person struct {
	Name string
	Age Int
}

func main() {
	input := []Person{
		{Name: "John", Age: 22},
		{Name: "Doe", Age: 23},
	}
	var output []string

	godash.Map(input, &output, func(person Person) string {
		return person.Name
	})

	fmt.Println(output) // prints John Doe
}
func main() {
	input := map[string]int{
			"key1": 1,
			"key2": 2,
			"key3": 3,
		}
	var output []int

	godash.Map(input, &output, func(el int) int {
		return el * el
	})

	fmt.Println(output) // prints 1 4 9
}
Filter

Filter out elements that fail the predicate. For more docs.

func main() {
	input := []int{1, 2, 3, 4, 5}
	var output []int

	godash.Filter(input, &output, func(element int) bool {
		return element % 2 == 0
	})

	fmt.Println(output) // prints 2 4
}
func main() {
	input := []Person{
		{Name: "John", Age: 20},
		{Name: "Doe", Age: 30},
	}
	var output []string

	godash.Filter(input, &output, func(person Person) bool {
		return person.Age > 25
	})

	fmt.Println(output) // prints {Doe 30}
}
Reduce

Reduce can accept a reducer and apply the reducer on each element of the input slice while providing an accumulator to save the reduce output. For more docs.

func main() {
    input := []string{"count", "words", "and", "print", "words", "count"}
	accumulator := map[string]int{}

	_ = godash.Reduce(input, &accumulator, func(acc map[string]int, element string) map[string]int {
		if _, present := acc[element]; present {
			acc[element] = acc[element] + 1
		} else {
			acc[element] = 1
		}
		return acc
	})

	bytes, _ := json.MarshalIndent(accumulator, "", "  ")
	fmt.Println(string(bytes))

	// Output:
	//{
	//   "and": 1,
	//   "count": 2,
	//   "print": 1,
	//   "words": 2
	//}

}
func main() {
	input := []Person{
		{Name: "John", Age: 22},
		{Name: "Doe", Age: 23},
	}
	var output int

	godash.Reduce(input, &output, func(sum int, person Person) int {
		return sum + person.Age
	})

	fmt.Println(output) // prints 45
}
Any or Some

Any or Some checks if predicate returns truthy for any element of collection. Iteration is stopped once predicate returns truthy. For more docs.

func main() {
	input := []int{1, 2, 3, 4, 5}
	var output []int
	output, _ := godash.Any(input, func(num int) bool {
		return num % 7 == 0
	})
	fmt.Println(output) // prints false
}
func main() {
	input := []Person{
		{Name: "John", Age: 25},
		{Name: "Doe", Age: 15},
	}
	var output int
	output, _ := godash.Some(input, func(person Person) bool {
		return person.Age < 18
	})
	fmt.Println(output) // prints true
}
Find

Returns the first element which passes the predicate. For more docs.

func main() {
	input := []string{"john","wick","will"}
	var output string

	godash.Find(input, &output, func(element string) bool {
    	return strings.HasPrefix(element, "w") // starts with
	}
	// output is "wick"
	fmt.Println(output)
}
All or Every

All or Every checks if predicate returns truthy for all element of collection. Iteration is stopped once predicate returns falsely. For more docs.

func main() { 
	input := []int{1, 2, 3, 4, 5} 
	var output bool 
	output, _ := godash.All(input, func(num int) bool { 
		return num >= 1 
	}) 
	fmt.Println(output) // prints true 
} 
func main() { 
	input := []Person{ 
		{Name: "John", Age: 25}, 
		{Name: "Doe", Age: 15}, 
	} 
	var output bool 
	output, _ := godash.Every(input, func(person Person) bool {
		return person.Age < 18 
	}) 
	fmt.Println(output) // prints false 
}

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func All

func All(in, predicateFn interface{}) (bool, error)

All checks if predicate returns truthy for all element of collection. Iteration is stopped once predicate returns falsely. Currently, input of type slice is supported

Validations:

1. Predicate function should take one argument and return one value 2. Predicate function should return a bool value 3. Predicate function's argument should be of the same type as the elements of the input slice

Validation errors are returned to the caller

Example
package main

import (
	"fmt"

	"github.com/thecasualcoder/godash"
)

func main() {
	input := []int{0, 1, 2, 3, 4}

	output, _ := godash.All(input, func(num int) bool {
		return num >= 0
	})

	fmt.Println(output)

}
Output:

true

func Any

func Any(in, predicateFn interface{}) (bool, error)

Any checks if predicate returns truthy for any element of collection. Iteration is stopped once predicate returns truthy. Currently, input of type slice is supported

Validations:

1. Predicate function should take one argument and return one value 2. Predicate function should return a bool value 3. Predicate function's argument should be of the same type as the elements of the input slice

Validation errors are returned to the caller

Example
package main

import (
	"fmt"
	"github.com/thecasualcoder/godash"
)

func main() {
	input := []int{0, 1, 2, 3, 4}

	output, _ := godash.Any(input, func(num int) bool {
		return num%3 == 0
	})

	fmt.Println(output)

}
Output:

true

func Every

func Every(in, predicateFn interface{}) (bool, error)

Every is an alias for All function

Example
package main

import (
	"fmt"

	"github.com/thecasualcoder/godash"
)

func main() {
	input := []int{0, 1, 2, 3, 4}

	output, _ := godash.Every(input, func(num int) bool {
		return num >= 0
	})

	fmt.Println(output)

}
Output:

true

func Filter

func Filter(in, out, predicateFn interface{}) error

Filter out elements that fail the predicate.

Input of type slice is supported as of now. Output is a slice in which filtered-in elements are stored. PredicateFn function is applied on each element of input to determine to filter or not

Validations:

  1. Input and Output's slice should be of same type
  2. Predicate function can take one argument and return one argument
  3. Predicate's return argument is always boolean.
  4. Predicate's input argument should be input/output slice's element type.

Validation errors are returned to the caller.

Example
package main

import (
	"fmt"
	"github.com/thecasualcoder/godash"
)

func main() {
	input := []string{
		"rhythm",
		"of",
		"life",
	}
	var output []string

	_ = godash.Filter(input, &output, func(in string) bool {
		return len(in) > 3
	})

	fmt.Println(output)

}
Output:

[rhythm life]

func Find

func Find(in, out, predicateFn interface{}) error

Find out elements.

Input of type slice is supported as of now. Output is a elements are matched. PredicateFn function is applied on each element of input to determine to find element until it finds the element

Validations:

  1. Input's element type and Output should be of same type
  2. Predicate function can take one argument and return one argument
  3. Predicate's return argument is always boolean.
  4. Predicate's input argument should be output element type.

Validation errors are returned to the caller

Example
package main

import (
	"fmt"
	"strings"

	"github.com/thecasualcoder/godash"
)

func main() {
	input := []string{
		"rhythm",
		"of",
		"life",
	}
	var output string

	_ = godash.Find(input, &output, func(in string) bool {
		return strings.HasPrefix(in, "r")
	})
	fmt.Println(output)

}
Output:

rhythm

func Map

func Map(in, out, mapperFn interface{}) error

Map applies mapperFn on each item of in and puts it in out. Currently, input and output for type slice is supported.

Validations:

  1. Mapper function should take in one argument and return one argument
  2. Mapper function's argument should be of the same type of each element of input slice.
  3. Mapper function's output should be of the same type of each element of output slice.

Validation failures are returned as error by the godash.Map to the caller.

Example
package main

import (
	"fmt"
	"github.com/thecasualcoder/godash"
)

func main() {
	input := []int{0, 1, 2, 3, 4}
	var output []string

	_ = godash.Map(input, &output, func(num int) string {
		return fmt.Sprintf("%d", num*num)
	})

	fmt.Println(output)

}
Output:

[0 1 4 9 16]
Example (Map)
package main

import (
	"fmt"
	"github.com/thecasualcoder/godash"
	"sort"
)

func main() {
	input := map[string]int{"key1": 1, "key2": 2, "key3": 3, "key4": 4, "key5": 5}
	var output []int

	_ = godash.Map(input, &output, func(key string, num int) int {
		return num * num
	})

	sort.Ints(output)
	fmt.Println(output)

}
Output:

[1 4 9 16 25]

func Reduce

func Reduce(in, out, reduceFn interface{}) error

Reduce can accept a reducer and apply the reducer on each element of the input slice while providing an accumulator to save the reduce output.

Input of type slice is supported as of now. Output is the accumulator. ReduceFn is the reducer function.

Whatever ReduceFn returns is fed as accumulator for the next iteration. Reduction happens from left-to-right.

Reduce does the following validations:

  1. Reducer function should accept exactly 2 arguments and return 1 argument
  2. Reducer function's second argument should be the same type as input slice's element type
  3. Reducer function's return type should be the same as that of the accumulator

Validation errors are returned to the caller.

Example
package main

import (
	"encoding/json"
	"fmt"
	"github.com/thecasualcoder/godash"
)

func main() {
	input := []string{"count", "words", "and", "print", "words", "count"}
	accumulator := map[string]int{}

	_ = godash.Reduce(input, &accumulator, func(acc map[string]int, element string) map[string]int {
		if _, present := acc[element]; present {
			acc[element] = acc[element] + 1
		} else {
			acc[element] = 1
		}
		return acc
	})

	bytes, _ := json.MarshalIndent(accumulator, "", "  ")
	fmt.Println(string(bytes))

}
Output:

{
  "and": 1,
  "count": 2,
  "print": 1,
  "words": 2
}

func Some

func Some(in, predicateFn interface{}) (bool, error)

Some is an alias for Any function

Example
package main

import (
	"fmt"
	"github.com/thecasualcoder/godash"
)

func main() {
	input := []int{0, 1, 2, 3, 4}

	output, _ := godash.Some(input, func(num int) bool {
		return num%3 == 0
	})

	fmt.Println(output)

}
Output:

true

Types

This section is empty.

Jump to

Keyboard shortcuts

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