<commit_before>go-funk
=======

``go-funk`` is a modern Go library based on reflect_.

This project has started as an experiment to learn reflect_, feel free to use it :)

.. image:: https://secure.travis-ci.org/thoas/go-funk.svg?branch=master
    :alt: Build Status
    :target: http://travis-ci.org/thoas/go-funk

.. image:: https://godoc.org/github.com/thoas/go-funk?status.svg
    :alt: GoDoc
    :target: https://godoc.org/github.com/thoas/go-funk

.. image:: https://goreportcard.com/badge/github.com/thoas/go-funk
    :alt: Go report
    :target: https://goreportcard.com/report/github.com/thoas/go-funk


Installation
------------

.. code-block:: bash

    go get github.com/thoas/go-funk

Usage
-----

.. code-block:: go

    import "github.com/thoas/go-funk"

These examples will be based on the following data model:

.. code-block:: go

    type Foo struct {
        ID        int
        FirstName string `tag_name:"tag 1"`
        LastName  string `tag_name:"tag 2"`
        Age       int    `tag_name:"tag 3"`
    }

    func (f Foo) TableName() string {
        return "foo"
    }

With fixtures:

.. code-block:: go

    f := &Foo{
        ID:        1,
        FirstName: "Foo",
        LastName:  "Bar",
        Age:       30,
    }

You can import ``go-funk`` using a basic statement:

.. code-block:: go

    import "github.com/thoas/go-funk"

funk.SliceOf
............

``funk.SliceOf`` will return a slice based on an element.

.. code-block:: go

    result := funk.SliceOf(f) // will return a []*Foo{f}

funk.Contains
.............

``funk.Contains`` returns true if an element is present in a iteratee (slice, map, string).

One frustrating thing in Go is to implement ``contains`` methods for each types, for example:

.. code-block:: go

    func ContainsInt(s []int, e int) bool {
        for _, a := range s {
            if a == e {
                return true
            }
        }
        return false
    }

this can be replaced by ``funk.Contains``:

.. code-block:: go

    // slice of string
    funk.Contains([]string{"foo", "bar"}, "bar") // true

    // slice of Foo ptr
    funk.Contains([]*Foo{f}, f) // true
    funk.Contains([]*Foo{f}, nil) // false

    b := &Foo{
        ID:        2,
        FirstName: "Florent",
        LastName:  "Messa",
        Age:       28,
    }

    funk.Contains([]*Foo{f}, b) // false

    // string
    funk.Contains("florent", "rent") // true
    funk.Contains("florent", "foo") // false

    // even map
    funk.Contains(map[int]string{1: "Florent"}, 1) // true

funk.ToMap
..........

``funk.ToMap`` transforms a slice of structs to a map based on a ``pivot`` field.

.. code-block:: go

    f := &Foo{
        ID:        1,
        FirstName: "Gilles",
        LastName:  "Fabio",
        Age:       70,
    }

    b := &Foo{
        ID:        2,
        FirstName: "Florent",
        LastName:  "Messa",
        Age:       80,
    }

    results := []*Foo{f, b}

    mapping := funk.ToMap(results, "ID") // map[int]*Foo{1: f, 2: b}

funk.Filter
...........

``funk.Filter`` filters a slice based on a predicate.

.. code-block:: go

    r := funk.Filter([]int{1, 2, 3, 4}, func(x int) bool {
        return x%2 == 0
    }) // []int{2, 4}

funk.Find
.........

``funk.Find`` finds an element in a slice based on a predicate.

.. code-block:: go

    r := funk.Find([]int{1, 2, 3, 4}, func(x int) bool {
        return x%2 == 0
    }) // 2

funk.Map
........

``funk.Map`` allows you to manipulate an iteratee (map, slice) and to transform it to another type:

* map -> slice
* map -> map
* slice -> map
* slice -> slice

.. code-block:: go

    r := funk.Map([]int{1, 2, 3, 4}, func(x int) int {
        return "Hello"
    }) // []int{2, 4, 6, 8}

    r := funk.Map([]int{1, 2, 3, 4}, func(x int) string {
        return "Hello"
    }) // []string{"Hello", "Hello", "Hello", "Hello"}

    r = funk.Map([]int{1, 2, 3, 4}, func(x int) (int, int) {
        return x, x
    }) // map[int]int{1: 1, 2: 2, 3: 3, 4: 4}

    mapping := map[int]string{
        1: "Florent",
        2: "Gilles",
    }

    r = funk.Map(mapping, func(k int, v string) int {
        return k
    }) // []int{1, 2}

    r = funk.Map(mapping, func(k int, v string) (string, string) {
        return fmt.Sprintf("%d", k), v
    }) // map[string]string{"1": "Florent", "2": "Gilles"}

funk.ForEach
............

``funk.ForEach`` allows you to range over an iteratee (map, slice)

.. code-block:: go

    funk.ForEach([]int{1, 2, 3, 4}, func(x int) {
        fmt.Println(x)
    })

funk.Chunk
..........

``funk.Chunk`` creates an array of elements split into groups with the length
of the size. If array can't be split evenly, the final chunk will be the remaining element.

.. code-block:: go

    funk.Chunk([]int{1, 2, 3, 4, 5}, 2) // [][]int{[]int{1, 2}, []int{3, 4}, []int{5}}

funk.FlattenDeep
................

``funk.FlattenDeep`` recursively flattens array.

.. code-block:: go

    funk.FlattenDeep([][]int{[]int{1, 2}, []int{3, 4}}) // []int{1, 2, 3, 4}

funk.Get
........

``funk.Get`` retrieves the value at path of struct(s).

.. code-block:: go

    var bar *Bar = &Bar{
        Name: "Test",
        Bars: []*Bar{
            &Bar{
                Name: "Level1-1",
                Bar: &Bar{
                    Name: "Level2-1",
                },
            },
            &Bar{
                Name: "Level1-2",
                Bar: &Bar{
                    Name: "Level2-2",
                },
            },
        },
    }

    var foo *Foo = &Foo{
        ID:        1,
        FirstName: "Drew",
        LastName:  "Olson",
        Age:       30,
        Bar:       bar,
        Bars: []*Bar{
            bar,
            bar,
        },
    }

    Get([]*Foo{foo}, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
    Get(foo, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
    Get(foo, "Bar.Name") // Test


Contributing
------------

* Ping me on twitter `@thoas <https://twitter.com/thoas>`_
* Fork the `project <https://github.com/thoas/go-funk>`_
* Fix `open issues <https://github.com/thoas/go-funk/issues>`_ or request new features

Don't hesitate ;)

.. _reflect: https://golang.org/pkg/reflect/
<commit_msg>Add runtime warning<commit_after>go-funk
=======

``go-funk`` is a modern Go library based on reflect_.

This project has started as an experiment to learn reflect_, feel free to use it :)

As it relies a lot on reflect_, be careful this code runs exclusively on runtime so you must have a good test suite.

.. image:: https://secure.travis-ci.org/thoas/go-funk.svg?branch=master
    :alt: Build Status
    :target: http://travis-ci.org/thoas/go-funk

.. image:: https://godoc.org/github.com/thoas/go-funk?status.svg
    :alt: GoDoc
    :target: https://godoc.org/github.com/thoas/go-funk

.. image:: https://goreportcard.com/badge/github.com/thoas/go-funk
    :alt: Go report
    :target: https://goreportcard.com/report/github.com/thoas/go-funk


Installation
------------

.. code-block:: bash

    go get github.com/thoas/go-funk

Usage
-----

.. code-block:: go

    import "github.com/thoas/go-funk"

These examples will be based on the following data model:

.. code-block:: go

    type Foo struct {
        ID        int
        FirstName string `tag_name:"tag 1"`
        LastName  string `tag_name:"tag 2"`
        Age       int    `tag_name:"tag 3"`
    }

    func (f Foo) TableName() string {
        return "foo"
    }

With fixtures:

.. code-block:: go

    f := &Foo{
        ID:        1,
        FirstName: "Foo",
        LastName:  "Bar",
        Age:       30,
    }

You can import ``go-funk`` using a basic statement:

.. code-block:: go

    import "github.com/thoas/go-funk"

funk.SliceOf
............

``funk.SliceOf`` will return a slice based on an element.

.. code-block:: go

    result := funk.SliceOf(f) // will return a []*Foo{f}

funk.Contains
.............

``funk.Contains`` returns true if an element is present in a iteratee (slice, map, string).

One frustrating thing in Go is to implement ``contains`` methods for each types, for example:

.. code-block:: go

    func ContainsInt(s []int, e int) bool {
        for _, a := range s {
            if a == e {
                return true
            }
        }
        return false
    }

this can be replaced by ``funk.Contains``:

.. code-block:: go

    // slice of string
    funk.Contains([]string{"foo", "bar"}, "bar") // true

    // slice of Foo ptr
    funk.Contains([]*Foo{f}, f) // true
    funk.Contains([]*Foo{f}, nil) // false

    b := &Foo{
        ID:        2,
        FirstName: "Florent",
        LastName:  "Messa",
        Age:       28,
    }

    funk.Contains([]*Foo{f}, b) // false

    // string
    funk.Contains("florent", "rent") // true
    funk.Contains("florent", "foo") // false

    // even map
    funk.Contains(map[int]string{1: "Florent"}, 1) // true

funk.ToMap
..........

``funk.ToMap`` transforms a slice of structs to a map based on a ``pivot`` field.

.. code-block:: go

    f := &Foo{
        ID:        1,
        FirstName: "Gilles",
        LastName:  "Fabio",
        Age:       70,
    }

    b := &Foo{
        ID:        2,
        FirstName: "Florent",
        LastName:  "Messa",
        Age:       80,
    }

    results := []*Foo{f, b}

    mapping := funk.ToMap(results, "ID") // map[int]*Foo{1: f, 2: b}

funk.Filter
...........

``funk.Filter`` filters a slice based on a predicate.

.. code-block:: go

    r := funk.Filter([]int{1, 2, 3, 4}, func(x int) bool {
        return x%2 == 0
    }) // []int{2, 4}

funk.Find
.........

``funk.Find`` finds an element in a slice based on a predicate.

.. code-block:: go

    r := funk.Find([]int{1, 2, 3, 4}, func(x int) bool {
        return x%2 == 0
    }) // 2

funk.Map
........

``funk.Map`` allows you to manipulate an iteratee (map, slice) and to transform it to another type:

* map -> slice
* map -> map
* slice -> map
* slice -> slice

.. code-block:: go

    r := funk.Map([]int{1, 2, 3, 4}, func(x int) int {
        return "Hello"
    }) // []int{2, 4, 6, 8}

    r := funk.Map([]int{1, 2, 3, 4}, func(x int) string {
        return "Hello"
    }) // []string{"Hello", "Hello", "Hello", "Hello"}

    r = funk.Map([]int{1, 2, 3, 4}, func(x int) (int, int) {
        return x, x
    }) // map[int]int{1: 1, 2: 2, 3: 3, 4: 4}

    mapping := map[int]string{
        1: "Florent",
        2: "Gilles",
    }

    r = funk.Map(mapping, func(k int, v string) int {
        return k
    }) // []int{1, 2}

    r = funk.Map(mapping, func(k int, v string) (string, string) {
        return fmt.Sprintf("%d", k), v
    }) // map[string]string{"1": "Florent", "2": "Gilles"}

funk.ForEach
............

``funk.ForEach`` allows you to range over an iteratee (map, slice)

.. code-block:: go

    funk.ForEach([]int{1, 2, 3, 4}, func(x int) {
        fmt.Println(x)
    })

funk.Chunk
..........

``funk.Chunk`` creates an array of elements split into groups with the length
of the size. If array can't be split evenly, the final chunk will be the remaining element.

.. code-block:: go

    funk.Chunk([]int{1, 2, 3, 4, 5}, 2) // [][]int{[]int{1, 2}, []int{3, 4}, []int{5}}

funk.FlattenDeep
................

``funk.FlattenDeep`` recursively flattens array.

.. code-block:: go

    funk.FlattenDeep([][]int{[]int{1, 2}, []int{3, 4}}) // []int{1, 2, 3, 4}

funk.Get
........

``funk.Get`` retrieves the value at path of struct(s).

.. code-block:: go

    var bar *Bar = &Bar{
        Name: "Test",
        Bars: []*Bar{
            &Bar{
                Name: "Level1-1",
                Bar: &Bar{
                    Name: "Level2-1",
                },
            },
            &Bar{
                Name: "Level1-2",
                Bar: &Bar{
                    Name: "Level2-2",
                },
            },
        },
    }

    var foo *Foo = &Foo{
        ID:        1,
        FirstName: "Drew",
        LastName:  "Olson",
        Age:       30,
        Bar:       bar,
        Bars: []*Bar{
            bar,
            bar,
        },
    }

    Get([]*Foo{foo}, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
    Get(foo, "Bar.Bars.Bar.Name") // []string{"Level2-1", "Level2-2"}
    Get(foo, "Bar.Name") // Test


Contributing
------------

* Ping me on twitter `@thoas <https://twitter.com/thoas>`_
* Fork the `project <https://github.com/thoas/go-funk>`_
* Fix `open issues <https://github.com/thoas/go-funk/issues>`_ or request new features

Don't hesitate ;)

.. _reflect: https://golang.org/pkg/reflect/

{'fraction_non_alphanumeric': 0.18805732484076434, 'fraction_numerical': 0.016878980891719745, 'mean_word_length': 1.8664993153811045, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 18, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1002057', 'n_tokens_mistral': 4681, 'n_tokens_neox': 4401, 'n_words': 1233}