Helpfully Functional Go - A useful collection of Go utilities. Designed for programmer happiness.

Underscore.go

Move Fast; Optimize Late

A useful collection of Go utilities. Designed for programmer happiness.

TL;DR Sort-of like underscore.js, but for Go

API Documention

GoDoc is WorkInProgress

⚠️ Warning

This package is in heavy flux at the moment as I work to incorporate feedback from various sources.

:squirrel: Todo

  • godoc
  • contains
  • indexOf
  • worker pools
  • parallel each
  • parallel map with worker pool
  • refactor to make functions first parameter (eg Each func(func(A), []A))
  • handle maps & slices
  • all
  • any
  • none

Typed Functions


Any


Each


Each func(func(A int), []A) Each func(func(A B), []A)

Applies the given iterator function to each element of a collection (slice or map).

If the collection is a Slice, the iterator function arguments are value, index

If the collection is a Map, the iterator function arguments are value, key

EachP is a Parallel implementation of Each and concurrently applies the given iterator function to each element of a collection (slice or map).

  // var Each func(func(value interface{}, i interface{}), interface{})

  var buffer bytes.Buffer

  fn := func(s, i interface{}) {
    buffer.WriteString(s.(string))
  }

  s := []string{"a", "b", "c", "d", "e"}
  Each(fn, s)

  expect := "abcde"

  e := un.Each(fn, s)

  fmt.Printf("%#v\n", e) //"abcde"

Typed Each can be defined using a function type and the MakeEach helper.

Using a Typed Slice

  var EachInt func(func(value, i int), []int)
  MakeEach(&EachInt)

  var sum int

  fn := func(v, i int) {
    sum += v
  }

  i := []int{1, 2, 3, 4, 5}
  EachInt(fn, i)

  fmt.Printf("%#v\n", sum) //15

Using a Typed Map

  var EachStringInt func(func(key string, value int), map[string]int)
  var sum int

  fn := func(v int, k string) {
    sum += v
  }

  m := map[string]int{"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}
  EachStringInt(fn, m)

  fmt.Printf("%#v\n", sum) //15

Of note is the ability to close over variables within the calling scope.

Every


Map


Map func([]A, func(A) B) []B

Applies the given function to each element of a slice, returning a slice of results

The base Map function accepts interface{} types and returns []interface{}

  // Map func(interface{}, func(interface{}) interface{}) []interface{}

  s := []string{"a", "b", "c", "d"}

  fn := func(s interface{}) interface{} {
    return s.(string) + "!"
  }

  m := un.Map(ToI(s), fn)
  fmt.Println(m) //["a!", "b!", "c!", "d!"]

Typed Maps can be defined using a function type and the MakeMap helper.

  Map func([]A, func(A) B) []B

  var SMap func([]string, func(string) string) []string
  un.MakeMap(&SMap)

  m := un.SMap(s, fn)
  fmt.Println(m) //["a!", "b!", "c!", "d!"]

Of note is the return value of Map is a slice of the return type of the applied function.

Partition


Partition func([]A, func(A) bool) ([]A []A)

Partition splits a slice or map based on the evaluation of the supplied function

The base Partition function accepts interface{} types and returns []interface{}

  // Partition func(interface{}, func(interface{}) bool) ([]interface{}, []interface{})

  s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

  fn := func(i interface{}) bool {
    return (i.(int) % 2) == 1
  }

  odd, even := un.Partition(s, fn)

  fmt.Println(odd)  //[1, 3, 5, 7, 9]
  fmt.Println(even) //[2, 4, 6, 8, 10]

Typed Partitions can be defined using a function type and the MakePartition helper.

  // Partition func([]A, func(A) bool) ([]A []A)

  var IPartition func([]int, func(int) bool) ([]int, []int)

  un.MakePartition(&IPartition)

  s := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

  fn := func(i int) bool {
    return (i % 2) == 1
  }

  odd, even := un.IPartition(s, fn)

  fmt.Println(odd)  //[1, 3, 5, 7, 9]
  fmt.Println(even) //[2, 4, 6, 8, 10]

Contains returns true if an object is in a slice.

  o := "a"
  s := []string{"a", "b", "c"}

  b := un.Contains(s, o)
  fmt.Println(b) //true

ToI converts a slice of arbitrary type []T into a slice of []interfaces{}

  s := []int{1, 1, 3, 5, 8, 13}
  i := un.ToI(s)

Notes

I am aware that the whole idea is not particularly very TheGoWay™, but it is useful as a learning exercise, and it is useful for moving fast and optimising later.

Comments
  • Actively development

    Actively development

    Is this library under actively development now? I am interested in developing and maintaining the library. But just realised that the last commit is 4 years ago.

  • README Fixes

    README Fixes

    I stumbled upon this package on Reddit and it looked interesting. I noticed some problems in the README as I was checking it out so I decided to pitch in and fix them.

    But FYI the "go way" is to add comments to your source code such that GoDoc can parse and present your full documentation (see: underscore.go vs goji/web).

  • 
Fix function comments based on best practices from Effective Go

    Fix function comments based on best practices from Effective Go

    Every exported function in a program should have a doc comment. The first sentence should be a summary that starts with the name ({{funcName}}) being declared. From effective go.

    PR generated by CodeLingo. Install here to drive Continuous Higher Standards.

  • several suggestions

    several suggestions

    I browsed your code and have some suggestions.

    first, I think underscore need a more general function instead of specifying a function for a certain type,for instance in order to map string you need to specify a SMap function pointer.Your code was excellent,could be there any way to implement such general function? such like not returning []interface{},but receive a point of return value as argument,in order to reflect the result.

    second, in Each, I think sync.WaitGroup is more comlicated because it is implemented by lock,and why not do like

    
    var done = make(chan struct{}{},m.Len()) //m is the map or slice
    for i:= 0;i<s.Len();i++{
        go func(){
            donw <-
        }() 
    }
    
    for i:= 0;i<s.Len();i++{
        done <-
    }
    
    

    I thins this dose the same work,but in more Go way.

    third, function decleration is not constant,Each has argument name but Map does not which will make some confusion.

    fourth chan argument should be more strict ,to spefigy read-only or write-only reader need argument like job <- chan,which should only read from in the function body.

    fifth , jobs in Each should be bufferd capabible of len of workers number, so that workers will not block on read or write and will be more akin parallel

    That's my thoughts,maybe it's wrong or not appropriate,hoping to discuss!

  • Make package

    Make package "go get" compatible

    There are two things which prevent this package from being go get compatible and idiomatic. The first can be fixed with a pull request, but the second requires changing the repository name/location.

    Go projects use a single directory for all files in a package, and this directory generally has the same name as the package name (so src directories aren't used in Go projects).

    However, project names that end in .go are no longer recognized by the entire Go toolchain, which means that the project name should really be underscore (or perhaps __, not `underscore.go).

    (I was going to submit a pull request, but then I realized that the respository name ended in .go, which ideally should be fixed before moving the files out of the src directory; doing this in the other order would result in an inconsistent intermediate state.)

A collection of functional operators for golang with generics

fn fn is a collection of go functional operators with generics Getting Started P

Jul 8, 2022
A collection of small Go utilities to make life easier.

The simplego package provides a collection of Go utilities for common tasks.

Jan 4, 2023
Go-Utils is a library containing a collection of Golang utilities

Go-Utils is a library containing a collection of Golang utilities

Jun 2, 2022
Code Generation for Functional Programming, Concurrency and Generics in Golang

goderive goderive derives mundane golang functions that you do not want to maintain and keeps them up to date. It does this by parsing your go code fo

Dec 25, 2022
Make Go functional with dogs
Make Go functional with dogs

dogs Make Go functional with dogs Caution This is a highly-experimental package. Any changes will be made in a backward-incompatible manner. This pack

Jan 4, 2023
Functional tools in Go 1.18 using newly introduced generics

functools functools is a simple Go library that brings you your favourite functi

Dec 5, 2022
Experimenting with golang generics to implement functional favorites like filter, map, && reduce.

funcy Experimenting with golang generics to implement functional favorites like filter, map, && reduce. 2021-12 To run the tests, you need to install

Dec 29, 2021
F - Experimenting with Go 1.18 generics to write more functional Go code

f f is a simple library that leverages the new generics in Golang to create a tools for functional style of code. Pipe like '|>' in Elixir or Elm. inp

Apr 12, 2022
Utilities to generate (reference) documentation for the docker CLI

About This is a library containing utilities to generate (reference) documentation for the docker CLI on docs.docker.com. Disclaimer This library is i

Dec 28, 2022
Utilities for interacting with Dockerfiles
Utilities for interacting with Dockerfiles

go-dockerfile Golang utilities for interacting with Dockerfiles. This is not a place of honor. No esteemed source code is commemorated here. Don't tak

Apr 6, 2022
CUE utilities and helpers for working with tree based objects in any combination of CUE, Yaml, and JSON.

Cuetils CUE utilities and helpers for working with tree based objects in any combination of CUE, Yaml, and JSON. Using As a command line binary The cu

Dec 24, 2022
Simple utilities for creating ascii text in Go

Simple utilities for creating ascii text in Go

Oct 30, 2021
golden provides utilities for golden file tests.

golden provides utilities for golden file tests.

Dec 27, 2022
Source Repo for utilities used in Atlas

Atlas-Utilities Source Repo for utilities used in Atlas filepicker Simple file picker in Go using go-common-file-dialog This returns the path of a fil

Dec 25, 2022
List-Utils - 🔧 Utilities for maintaining the list of repost sites

SMR List Utils This is a Go CLI tool that helps with managing the StopModReposts blacklist. Install Use GitHub Releases and download binary. Linux Qui

Jan 3, 2022
Utilities for processing Wikipedia dumps in Go

Utilities for processing Wikipedia dumps in Go A Go package providing utilities for processing Wikipedia dumps. Features: Supports Wikidata entities J

Nov 29, 2022
Utilities for rounding and truncating floating point numbers.

Rounders Provides utilities for rounding and truncating floating point numbers. Example: rounders.RoundToDecimals(12.48881, 2)

Jan 6, 2022
Go-path - A helper package that provides utilities for parsing and using ipfs paths

go-path is a helper package that provides utilities for parsing and using ipfs paths

Jan 18, 2022
Goety - Generics based Go utilities

goety General purpose Go utilities. Package channel Utilities to work with chann

May 16, 2022