Skip to content

Commit

Permalink
doc: improve doc for lo.Interleave
Browse files Browse the repository at this point in the history
  • Loading branch information
samber committed Oct 10, 2022
1 parent ca01e36 commit e3f7dab
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 83 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,8 +507,13 @@ Round-robbin alternating input slices and sequentially appending value at index
```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}

interleaved := lo.Interleave[int]([]int{1}, []int{2, 5, 8}, []int{3, 6}, []int{4, 7, 9, 10})
// []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
```

[[play](https://go.dev/play/p/DDhlwrShbwe)]

### Shuffle

Returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
Expand Down
75 changes: 38 additions & 37 deletions slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,44 @@ func Flatten[T any](collection [][]T) []T {
return result
}

// Interleave round-robbin alternating input slices and sequentially appending value at index into result
// Play: https://go.dev/play/p/DDhlwrShbwe
func Interleave[T any](collections ...[]T) []T {
if len(collections) == 0 {
return []T{}
}

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
}

// Shuffle returns an array of shuffled values. Uses the Fisher-Yates shuffle algorithm.
// Play: https://go.dev/play/p/Qp73bnTDnc7
func Shuffle[T any](collection []T) []T {
Expand Down Expand Up @@ -546,40 +584,3 @@ func IsSortedByKey[T any, K constraints.Ordered](collection []T, iteratee func(T

return true
}

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

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
}
14 changes: 14 additions & 0 deletions slice_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,20 @@ func ExampleFlatten() {
// Output: [0 1 2 3 4 5]
}

func ExampleInterleave() {
list1 := [][]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
list2 := [][]int{{1}, {2, 5, 8}, {3, 6}, {4, 7, 9, 10}}

result1 := Interleave(list1...)
result2 := Interleave(list2...)

fmt.Printf("%v\n", result1)
fmt.Printf("%v\n", result2)
// Output:
// [1 2 3 4 5 6 7 8 9]
// [1 2 3 4 5 6 7 8 9 10]
}

func ExampleShuffle() {
list := []int{0, 1, 2, 3, 4, 5}

Expand Down
92 changes: 46 additions & 46 deletions slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,52 @@ func TestFlatten(t *testing.T) {
is.Equal(result1, []int{0, 1, 2, 3, 4, 5})
}

func TestInterleave(t *testing.T) {
tests := []struct {
name string
collections [][]int
want []int
}{
{
"nil",
[][]int{nil},
[]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)
}
})
}
}

func TestShuffle(t *testing.T) {
t.Parallel()
is := assert.New(t)
Expand Down Expand Up @@ -667,49 +713,3 @@ func TestIsSortedByKey(t *testing.T) {
return ret
}))
}

func TestInterleave(t *testing.T) {
tests := []struct {
name string
collections [][]int
want []int
}{
{
"nil",
[][]int{nil},
[]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)
}
})
}
}

0 comments on commit e3f7dab

Please sign in to comment.