samber/lo 使ってみた
repo
install
go get github.com/samber/lo@v1
Filter
要素とindexを使ったフィルターができる
	list := []string{"a", "b", "c"}
	pp.Println(lo.Filter(list, func(x string, i int) bool {
		return x == "a"
	}))
$ go run .
[]string{
  "a",
}
Map
射影操作。goの辞書(Map)とは関係ない
	pp.Println(lo.Map(list, func(x string, i int) int {
		return i
	}))
$ go run .
[]int{
  0,
  1,
  2,
}
FilterMap
FilterとMapを組み合わせた処理。第二引数で要素に含めるか。
	pp.Println(lo.FilterMap(list, func(x string, i int) (int, bool) {
		if i == 0 {
			return i, true
		}
		return i, false
	}))
[]int{
  0,
}
FlatMap
要素をリストに変換後に平坦化する
list := []int{1, 2, 3}
	pp.Println(lo.FlatMap(list, func(x int, i int) []string {
		return []string{
			strconv.Itoa(x),
			strconv.Itoa(x),
		}
	}))
$ go run .
[]string{
  "1",
  "1",
  "2",
  "2",
  "3",
  "3",
}
Reduce
リストを縮小する
	pp.Println(lo.Reduce(list, func(agg int, x int, i int) int {
		return agg + x
	}, 0))
6
ForEach
	lo.ForEach(list, func(x int, i int) {
		pp.Println(x * 2)
	})
2
4
6
Times
繰り返す
	pp.Println(lo.Times(3, func(i int) int {
		return i
	}))
[]int{
  0,
  1,
  2,
}
Uniq
pp.Println(lo.Uniq(list))
[]int{
  1,
  2,
  3,
}
UniqBy
        list := []int{1, 2, 3, 3}
	pp.Println(lo.UniqBy(list, func(x int) int {
		return x % 2
	}))
[]int{
  1,
  2,
}
GroupBy
戻り値をMapのキーにしてMapを作成
	pp.Println(lo.GroupBy(list, func(x int) int {
		return x % 2
	}))
map[int][]int{
  0: []int{
    2,
  },
  1: []int{
    1,
    3,
    3,
  },
}
Chunk
	pp.Println(lo.Chunk(list, 2))
[][]int{
  []int{
    1,
    2,
  },
  []int{
    3,
    3,
  },
}
PartitionBy
配列に分割する。GroupByはMapで分割するがPartitionByは配列に分割する
	pp.Println(lo.PartitionBy(list, func(x int) string {
		if x <= 2 {
			return "hoge"
		}
		return "fuga"
	}))
[][]int{
  []int{
    1,
    2,
  },
  []int{
    3,
    3,
  },
}
Flatten
2次元配列を1次元配列に変換
	pp.Println(lo.Flatten([][]int{list, list}))
[]int{
  1,
  2,
  3,
  3,
  1,
  2,
  3,
  3,
}
Shuffle
	rand.Seed(time.Now().UnixNano())
	pp.Println(lo.Shuffle([]int{8, 2, 3, 4, 5, 6, 7}))
[]int{
  1,
  3,
  7,
  2,
  4,
  6,
  5,
}
Reverse
pp.Println(lo.Reverse(list))
[]int{
  3,
  3,
  2,
  1,
}
Fill
第二引数の要素を、第一引数の要素分cloneする
	foo1 := &foo{"a", "b"}
	foo2 := &foo{"a", "b"}
	pp.Println(lo.Fill([]*foo{foo1, foo2}, &foo{"c", "d"}))
	pp.Println(foo1, foo2)
[]*main.foo{
  &main.foo{
    p1: "c",
    p2: "d",
  },
  &main.foo{
    p1: "c",
    p2: "d",
  },
}
&main.foo{
  p1: "a",
  p2: "b",
} &main.foo{
  p1: "a",
  p2: "b",
}
Repeat
Fillは配列を渡す必要があったが、Repeatはclone数を渡せばok
pp.Println(lo.Repeat(2, &foo{"a", "b"}))
[]*main.foo{
  &main.foo{
    p1: "a",
    p2: "b",
  },
  &main.foo{
    p1: "a",
    p2: "b",
  },
}
RepeatBy
	pp.Println(lo.RepeatBy(2, func(i int) string {
		return strconv.Itoa(i)
	}))
[]string{
  "0",
  "1",
}
KeyBy
funcで返した値をkeyにしてmapを作る
GroupByは同じkeyを配列にまとめるが、KeyByは同じKeyの値は上書きされる
	pp.Println(lo.KeyBy([]*foo{{"a", "a1"}, {"b", "b1"}, {"b", "b2"}}, func(x *foo) string {
		return x.p1
	}))
map[string]*main.foo{
  "a": &main.foo{
    p1: "a",
    p2: "a1",
  },
  "b": &main.foo{
    p1: "b",
    p2: "b2",
  },
}
Associate (SliceToMap)
KeyByと似てる。任意のkeyとvalueを返すことで配列をmapに変換。
KeyByは配列の要素がvalueになるが、Associateは任意のvalueに変換できる
	pp.Println(lo.Associate([]*foo{{"a", "a1"}, {"b", "b1"}, {"b", "b2"}}, func(x *foo) (string, string) {
		return x.p1, x.p2
	}))
map[string]string{
  "b": "b2",
  "a": "a1",
}
Drop
左からx個の要素を削除。
要素数を超えて削除してもpanicしない
	pp.Println(lo.Drop([]int{0, 1, 2, 3, 4, 5}, 2))
[]int{
  2,
  3,
  4,
  5,
}
	pp.Println(lo.Drop([]int{0, 1}, 5))
[]int{}
DropRight
Dropの右から版
	pp.Println(lo.DropRight([]int{0, 1, 2, 3, 4}, 2))
[]int{
  0,
  1,
  2,
}
DropWhile
falseを返すまで要素をDropする。
Filterは全ての要素にFunc実行するが、DropWhileは一度false返したら以降の要素はreturnに含まれる
戻り値の配列が、引数の配列と要素順逆になっているの注意
	pp.Println(lo.DropWhile([]int{0, 1, 2, 3, 1, 2, 3}, func(x int) bool {
		return x <= 2
	}))
[]int{
  3,
  1,
  2,
  3,
}
Replace
指定した数だけoldをnewに置換する
nを-1にするとReplaceAllと同じになる
	pp.Println(lo.Replace([]int{0, 1, 2, 3, 0, 0}, 0, 1, 1))
[]int{
  1,
  1,
  2,
  3,
  0,
  0,
}
	pp.Println(lo.Replace([]int{0, 1, 2, 3, 0, 0}, 0, 1, 2))
[]int{
  1,
  1,
  2,
  3,
  1,
  0,
}
	pp.Println(lo.Replace([]int{0, 1, 2, 3, 0, 0}, 0, 1, -1))
[]int{
  1,
  1,
  2,
  3,
  1,
  1,
}
ReplaceAll
Replace(collection, old, new, -1)
Compact
ゼロ値を除外する
pp.Println(lo.Compact([]int{0, 1, 0, 2, 3}))
[]int{
  1,
  2,
  3,
}
IsSorted
pp.Println(lo.IsSorted([]int{0, 1, 2, 3, 4}))
true
Keys
pp.Println(lo.Keys(map[int]string{1: "aaa", 2: "bbb"}))
[]int{
  1,
  2,
}
Values
Keysのvalue版
Ternary
三項演算子的な  if true ? "a" : "b"
pp.Println(lo.Ternary(true, "a", "b"))
"a"