mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
Merge pull request #19 from IBM/cleue-implement-first-and-last
fix: add first and last
This commit is contained in:
26
iterator/stateless/first.go
Normal file
26
iterator/stateless/first.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// 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://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 stateless
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/iterator/stateless/generic"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// First returns the first item in an iterator if such an item exists
|
||||||
|
func First[U any](mu Iterator[U]) O.Option[U] {
|
||||||
|
return G.First[Iterator[U]](mu)
|
||||||
|
}
|
41
iterator/stateless/first_test.go
Normal file
41
iterator/stateless/first_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// 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://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 stateless
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestFirst(t *testing.T) {
|
||||||
|
|
||||||
|
seq := From(1, 2, 3)
|
||||||
|
|
||||||
|
fst := First(seq)
|
||||||
|
|
||||||
|
assert.Equal(t, O.Of(1), fst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoFirst(t *testing.T) {
|
||||||
|
|
||||||
|
seq := Empty[int]()
|
||||||
|
|
||||||
|
fst := First(seq)
|
||||||
|
|
||||||
|
assert.Equal(t, O.None[int](), fst)
|
||||||
|
}
|
30
iterator/stateless/generic/first.go
Normal file
30
iterator/stateless/generic/first.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
// 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://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"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
|
||||||
|
// First returns the first item in an iterator if such an item exists
|
||||||
|
func First[GU ~func() O.Option[T.Tuple2[GU, U]], U any](mu GU) O.Option[U] {
|
||||||
|
return F.Pipe1(
|
||||||
|
mu(),
|
||||||
|
O.Map(T.Second[GU, U]),
|
||||||
|
)
|
||||||
|
}
|
@@ -49,9 +49,8 @@ func FromArray[GU ~func() O.Option[T.Tuple2[GU, U]], US ~[]U, U any](as US) GU {
|
|||||||
})(as)
|
})(as)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce applies a function for each value of the iterator with a floating result
|
// reduce applies a function for each value of the iterator with a floating result
|
||||||
func Reduce[GU ~func() O.Option[T.Tuple2[GU, U]], U, V any](f func(V, U) V, initial V) func(GU) V {
|
func reduce[GU ~func() O.Option[T.Tuple2[GU, U]], U, V any](as GU, f func(V, U) V, initial V) V {
|
||||||
return func(as GU) V {
|
|
||||||
next, ok := O.Unwrap(as())
|
next, ok := O.Unwrap(as())
|
||||||
current := initial
|
current := initial
|
||||||
for ok {
|
for ok {
|
||||||
@@ -60,7 +59,11 @@ func Reduce[GU ~func() O.Option[T.Tuple2[GU, U]], U, V any](f func(V, U) V, init
|
|||||||
next, ok = O.Unwrap(next.F1())
|
next, ok = O.Unwrap(next.F1())
|
||||||
}
|
}
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reduce applies a function for each value of the iterator with a floating result
|
||||||
|
func Reduce[GU ~func() O.Option[T.Tuple2[GU, U]], U, V any](f func(V, U) V, initial V) func(GU) V {
|
||||||
|
return F.Bind23of3(reduce[GU, U, V])(f, initial)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToArray converts the iterator to an array
|
// ToArray converts the iterator to an array
|
||||||
|
27
iterator/stateless/generic/last.go
Normal file
27
iterator/stateless/generic/last.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// 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://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"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
T "github.com/IBM/fp-go/tuple"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Last returns the last item in an iterator if such an item exists
|
||||||
|
func Last[GU ~func() O.Option[T.Tuple2[GU, U]], U any](mu GU) O.Option[U] {
|
||||||
|
return reduce(mu, F.Ignore1of2[O.Option[U]](O.Of[U]), O.None[U]())
|
||||||
|
}
|
27
iterator/stateless/last.go
Normal file
27
iterator/stateless/last.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// 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://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 stateless
|
||||||
|
|
||||||
|
import (
|
||||||
|
G "github.com/IBM/fp-go/iterator/stateless/generic"
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Last returns the last item in an iterator if such an item exists
|
||||||
|
// Note that the function will consume the [Iterator] in this call completely, to identify the last element. Do not use this for infinite iterators
|
||||||
|
func Last[U any](mu Iterator[U]) O.Option[U] {
|
||||||
|
return G.Last[Iterator[U]](mu)
|
||||||
|
}
|
41
iterator/stateless/last_test.go
Normal file
41
iterator/stateless/last_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// 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://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 stateless
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
O "github.com/IBM/fp-go/option"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLast(t *testing.T) {
|
||||||
|
|
||||||
|
seq := From(1, 2, 3)
|
||||||
|
|
||||||
|
fst := Last(seq)
|
||||||
|
|
||||||
|
assert.Equal(t, O.Of(3), fst)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoLast(t *testing.T) {
|
||||||
|
|
||||||
|
seq := Empty[int]()
|
||||||
|
|
||||||
|
fst := Last(seq)
|
||||||
|
|
||||||
|
assert.Equal(t, O.None[int](), fst)
|
||||||
|
}
|
Reference in New Issue
Block a user