Open31

samber/lo 使ってみた

syysyy

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",
}
syysyy

Map
射影操作。goの辞書(Map)とは関係ない

	pp.Println(lo.Map(list, func(x string, i int) int {
		return i
	}))

$ go run .
[]int{
  0,
  1,
  2,
}
syysyy

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,
}
syysyy

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",
}
syysyy

Reduce
リストを縮小する

	pp.Println(lo.Reduce(list, func(agg int, x int, i int) int {
		return agg + x
	}, 0))
6
syysyy

ForEach

	lo.ForEach(list, func(x int, i int) {
		pp.Println(x * 2)
	})
2
4
6
syysyy

Times
繰り返す

	pp.Println(lo.Times(3, func(i int) int {
		return i
	}))
[]int{
  0,
  1,
  2,
}
syysyy

Uniq

pp.Println(lo.Uniq(list))
[]int{
  1,
  2,
  3,
}
syysyy

UniqBy

        list := []int{1, 2, 3, 3}
	pp.Println(lo.UniqBy(list, func(x int) int {
		return x % 2
	}))
[]int{
  1,
  2,
}
syysyy

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,
  },
}
syysyy

Chunk

	pp.Println(lo.Chunk(list, 2))
[][]int{
  []int{
    1,
    2,
  },
  []int{
    3,
    3,
  },
}
syysyy

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,
  },
}
syysyy

Flatten
2次元配列を1次元配列に変換

	pp.Println(lo.Flatten([][]int{list, list}))
[]int{
  1,
  2,
  3,
  3,
  1,
  2,
  3,
  3,
}
syysyy

Reverse

pp.Println(lo.Reverse(list))
[]int{
  3,
  3,
  2,
  1,
}
syysyy

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",
}
syysyy

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",
  },
}
syysyy

RepeatBy

	pp.Println(lo.RepeatBy(2, func(i int) string {
		return strconv.Itoa(i)
	}))
[]string{
  "0",
  "1",
}
syysyy

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",
  },
}
syysyy

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",
}
syysyy

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{}
syysyy

DropRight
Dropの右から版

	pp.Println(lo.DropRight([]int{0, 1, 2, 3, 4}, 2))
[]int{
  0,
  1,
  2,
}
syysyy

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,
}
syysyy

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,
}
syysyy

Compact
ゼロ値を除外する

pp.Println(lo.Compact([]int{0, 1, 0, 2, 3}))
[]int{
  1,
  2,
  3,
}
syysyy

IsSorted

pp.Println(lo.IsSorted([]int{0, 1, 2, 3, 4}))
true
syysyy

Keys

pp.Println(lo.Keys(map[int]string{1: "aaa", 2: "bbb"}))
[]int{
  1,
  2,
}
syysyy

Ternary
三項演算子的な if true ? "a" : "b"

pp.Println(lo.Ternary(true, "a", "b"))
"a"