Skip to content

Commit

Permalink
Merge pull request IBM#16 from IBM/cleue-add-zip
Browse files Browse the repository at this point in the history
Cleue add zip
  • Loading branch information
CarstenLeue committed Aug 3, 2023
2 parents 89265ee + 4ed0046 commit d69a13e
Show file tree
Hide file tree
Showing 30 changed files with 11,788 additions and 11,035 deletions.
52 changes: 52 additions & 0 deletions array/generic/zip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package generic

import (
F "github.com/IBM/fp-go/function"
N "github.com/IBM/fp-go/number"
T "github.com/IBM/fp-go/tuple"
)

// ZipWith applies a function to pairs of elements at the same index in two arrays, collecting the results in a new array. If one
// input array is short, excess elements of the longer array are discarded.
func ZipWith[AS ~[]A, BS ~[]B, CS ~[]C, FCT ~func(A, B) C, A, B, C any](fa AS, fb BS, f FCT) CS {
l := N.Min(len(fa), len(fb))
res := make(CS, l)
for i := l - 1; i >= 0; i-- {
res[i] = f(fa[i], fb[i])
}
return res
}

// Zip takes two arrays and returns an array of corresponding pairs. If one input array is short, excess elements of the
// longer array are discarded
func Zip[AS ~[]A, BS ~[]B, CS ~[]T.Tuple2[A, B], A, B any](fb BS) func(AS) CS {
return F.Bind23of3(ZipWith[AS, BS, CS, func(A, B) T.Tuple2[A, B]])(fb, T.MakeTuple2[A, B])
}

// Unzip is the function is reverse of [Zip]. Takes an array of pairs and return two corresponding arrays
func Unzip[AS ~[]A, BS ~[]B, CS ~[]T.Tuple2[A, B], A, B any](cs CS) T.Tuple2[AS, BS] {
l := len(cs)
as := make(AS, l)
bs := make(BS, l)
for i := l - 1; i >= 0; i-- {
t := cs[i]
as[i] = t.F1
bs[i] = t.F2
}
return T.MakeTuple2(as, bs)
}
38 changes: 38 additions & 0 deletions array/zip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package array

import (
G "github.com/IBM/fp-go/array/generic"
T "github.com/IBM/fp-go/tuple"
)

// ZipWith applies a function to pairs of elements at the same index in two arrays, collecting the results in a new array. If one
// input array is short, excess elements of the longer array are discarded.
func ZipWith[FCT ~func(A, B) C, A, B, C any](fa []A, fb []B, f FCT) []C {
return G.ZipWith[[]A, []B, []C, FCT](fa, fb, f)
}

// Zip takes two arrays and returns an array of corresponding pairs. If one input array is short, excess elements of the
// longer array are discarded
func Zip[A, B any](fb []B) func([]A) []T.Tuple2[A, B] {
return G.Zip[[]A, []B, []T.Tuple2[A, B]](fb)
}

// Unzip is the function is reverse of [Zip]. Takes an array of pairs and return two corresponding arrays
func Unzip[A, B any](cs []T.Tuple2[A, B]) T.Tuple2[[]A, []B] {
return G.Unzip[[]A, []B, []T.Tuple2[A, B]](cs)
}
56 changes: 56 additions & 0 deletions array/zip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) 2023 IBM Corp.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package array

import (
"fmt"
"testing"

T "github.com/IBM/fp-go/tuple"
"github.com/stretchr/testify/assert"
)

func TestZipWith(t *testing.T) {
left := From(1, 2, 3)
right := From("a", "b", "c", "d")

res := ZipWith(left, right, func(l int, r string) string {
return fmt.Sprintf("%s%d", r, l)
})

assert.Equal(t, From("a1", "b2", "c3"), res)
}

func TestZip(t *testing.T) {
left := From(1, 2, 3)
right := From("a", "b", "c", "d")

res := Zip[string](left)(right)

assert.Equal(t, From(T.MakeTuple2("a", 1), T.MakeTuple2("b", 2), T.MakeTuple2("c", 3)), res)
}

func TestUnzip(t *testing.T) {
left := From(1, 2, 3)
right := From("a", "b", "c")

zipped := Zip[string](left)(right)

unzipped := Unzip(zipped)

assert.Equal(t, right, unzipped.F1)
assert.Equal(t, left, unzipped.F2)
}
Loading

0 comments on commit d69a13e

Please sign in to comment.