From c9d013416792e70aae5289ccba989bb9c0d8788e Mon Sep 17 00:00:00 2001 From: dillon Date: Sun, 5 Jun 2022 22:17:27 -0500 Subject: [PATCH 1/3] initial interleave working --- README.md | 10 ++++++++++ slice.go | 41 +++++++++++++++++++++++++++++++++++++++++ slice_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+) diff --git a/README.md b/README.md index dc3fee1d..ac15afb3 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Supported helpers for slices: - Reject - Count - CountBy +- Interleave Supported helpers for maps: @@ -596,6 +597,15 @@ count := lo.CountBy[int]([]int{1, 5, 1}, func(i int) bool { // 2 ``` +### Interleave + +Round-robbin alternating input slices and sequentially appending value at index into result. + +```go +interleaved := lo.Interleave[int]([]int{1, 4, 7}, []int{2, 5, 8}, []int{3, 6, 9}) +// []int{1, 2, 3, 4, 5, 6, 7, 8, 9} +``` + ### Subset Return part of a slice. diff --git a/slice.go b/slice.go index 1fb781b1..51c8337c 100644 --- a/slice.go +++ b/slice.go @@ -406,3 +406,44 @@ func Replace[T comparable](collection []T, old T, new T, n int) []T { func ReplaceAll[T comparable](collection []T, old T, new T) []T { return Replace(collection, old, new, -1) } + +// Interleave round-robbin alternating input slices and sequentially appending value at index into result +func Interleave[T any](collections ...[]T) []T { + if len(collections) == 0 { + return []T{} + } + + if len(collections) == 1 { + return collections[0] + } + + maxSize := 0 + totalSize := 0 + for _, c := range collections { + size := len(c) + totalSize += size + if size > maxSize { + maxSize = size + } + } + + if maxSize == 0 { + return []T{} + } + + result := make([]T, totalSize) + + resultIdx := 0 + for i := 0; i < maxSize; i++ { + for j := range collections { + if len(collections[j])-1 < i { + continue + } + + result[resultIdx] = collections[j][i] + resultIdx++ + } + } + + return result +} diff --git a/slice_test.go b/slice_test.go index 9174b0ed..5f7d872d 100644 --- a/slice_test.go +++ b/slice_test.go @@ -2,6 +2,7 @@ package lo import ( "math" + "reflect" "strconv" "strings" "testing" @@ -455,3 +456,44 @@ func TestReplaceAll(t *testing.T) { is.Equal([]int{42, 1, 42, 1, 2, 3, 42}, out1) is.Equal([]int{0, 1, 0, 1, 2, 3, 0}, out2) } + +func TestInterleave(t *testing.T) { + tests := []struct { + name string + collections [][]int + want []int + }{ + { + "empty", + [][]int{}, + []int{}, + }, + { + "empties", + [][]int{{}, {}}, + []int{}, + }, + { + "same length", + [][]int{{1, 3, 5}, {2, 4, 6}}, + []int{1, 2, 3, 4, 5, 6}, + }, + { + "different length", + [][]int{{1, 3, 5, 6}, {2, 4}}, + []int{1, 2, 3, 4, 5, 6}, + }, + { + "many slices", + [][]int{{1}, {2, 5, 8}, {3, 6}, {4, 7, 9, 10}}, + []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := Interleave(tt.collections...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("Interleave() = %v, want %v", got, tt.want) + } + }) + } +} From 307f0eb164cc879b193c15cfb5aea2c27fb6b3e4 Mon Sep 17 00:00:00 2001 From: dillon Date: Sun, 5 Jun 2022 22:35:24 -0500 Subject: [PATCH 2/3] add nil case --- slice.go | 4 ---- slice_test.go | 5 +++++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/slice.go b/slice.go index 51c8337c..452765b5 100644 --- a/slice.go +++ b/slice.go @@ -413,10 +413,6 @@ func Interleave[T any](collections ...[]T) []T { return []T{} } - if len(collections) == 1 { - return collections[0] - } - maxSize := 0 totalSize := 0 for _, c := range collections { diff --git a/slice_test.go b/slice_test.go index 5f7d872d..df20d375 100644 --- a/slice_test.go +++ b/slice_test.go @@ -463,6 +463,11 @@ func TestInterleave(t *testing.T) { collections [][]int want []int }{ + { + "nil", + [][]int{nil}, + []int{}, + }, { "empty", [][]int{}, From 30b3e96bcb0c99a748b6ca8db518eb8f2e937233 Mon Sep 17 00:00:00 2001 From: dillonstreator Date: Tue, 27 Sep 2022 19:05:54 -0500 Subject: [PATCH 3/3] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4e40cab7..d068e727 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ GoDoc: [https://godoc.org/github.com/samber/lo](https://godoc.org/github.com/sam Supported helpers for slices: - - [Filter](#filter) - [Map](#map) - [FilterMap](#filtermap)