mirror of
https://github.com/duke-git/lancet.git
synced 2025-10-05 23:46:54 +08:00
Add functional predicate XNOR (#181)
Add new function, Xnor, designed to create a composed predicate representing the logical Exclusive NOR (XNOR) operation applied to a list of predicates. The XNOR operation is a logical operation that returns true only if all operands have the same boolean value
This commit is contained in:
@@ -3,6 +3,9 @@ package function
|
||||
// And returns a composed predicate that represents the logical AND of a list of predicates.
|
||||
// It evaluates to true only if all predicates evaluate to true for the given value.
|
||||
func And[T any](predicates ...func(T) bool) func(T) bool {
|
||||
if len(predicates) < 2 {
|
||||
panic("programming error: predicates count must be at least 2")
|
||||
}
|
||||
return func(value T) bool {
|
||||
for _, predicate := range predicates {
|
||||
if !predicate(value) {
|
||||
@@ -23,6 +26,9 @@ func Negate[T any](predicate func(T) bool) func(T) bool {
|
||||
// Or returns a composed predicate that represents the logical OR of a list of predicates.
|
||||
// It evaluates to true if at least one of the predicates evaluates to true for the given value.
|
||||
func Or[T any](predicates ...func(T) bool) func(T) bool {
|
||||
if len(predicates) < 2 {
|
||||
panic("programming error: predicates count must be at least 2")
|
||||
}
|
||||
return func(value T) bool {
|
||||
for _, predicate := range predicates {
|
||||
if predicate(value) {
|
||||
@@ -36,6 +42,9 @@ func Or[T any](predicates ...func(T) bool) func(T) bool {
|
||||
// Nor returns a composed predicate that represents the logical NOR of a list of predicates.
|
||||
// It evaluates to true only if all predicates evaluate to false for the given value.
|
||||
func Nor[T any](predicates ...func(T) bool) func(T) bool {
|
||||
if len(predicates) < 2 {
|
||||
panic("programming error: predicates count must be at least 2")
|
||||
}
|
||||
return func(value T) bool {
|
||||
for _, predicate := range predicates {
|
||||
if predicate(value) {
|
||||
@@ -45,3 +54,22 @@ func Nor[T any](predicates ...func(T) bool) func(T) bool {
|
||||
return true // Only returns true if all predicates evaluate to false
|
||||
}
|
||||
}
|
||||
|
||||
// Xnor returns a composed predicate that represents the logical XNOR of a list of predicates.
|
||||
// It evaluates to true only if all predicates evaluate to true or false for the given value.
|
||||
func Xnor[T any](predicates ...func(T) bool) func(T) bool {
|
||||
if len(predicates) < 2 {
|
||||
panic("programming error: predicates count must be at least 2")
|
||||
}
|
||||
return func(value T) bool {
|
||||
trueCount := 0
|
||||
for _, predicate := range predicates {
|
||||
if predicate(value) {
|
||||
trueCount++
|
||||
}
|
||||
}
|
||||
// XNOR is true if either all predicates are true or all are false
|
||||
// This is the same as saying trueCount is 0 (all false) or trueCount is len(predicates) (all true)
|
||||
return trueCount == 0 || trueCount == len(predicates)
|
||||
}
|
||||
}
|
||||
|
@@ -73,6 +73,22 @@ func ExampleNor() {
|
||||
// false
|
||||
}
|
||||
|
||||
func ExampleXnor() {
|
||||
isEven := func(i int) bool { return i%2 == 0 }
|
||||
isPositive := func(i int) bool { return i > 0 }
|
||||
|
||||
match := Xnor(isEven, isPositive)
|
||||
|
||||
fmt.Println(match(2))
|
||||
fmt.Println(match(-3))
|
||||
fmt.Println(match(3))
|
||||
|
||||
// Output:
|
||||
// true
|
||||
// true
|
||||
// false
|
||||
}
|
||||
|
||||
// func ExamplePredicatesMix() {
|
||||
// a := Or(
|
||||
// func(s string) bool { return strings.ContainsAny(s, "0123456789") },
|
||||
|
@@ -74,6 +74,21 @@ func TestPredicatesNorPure(t *testing.T) {
|
||||
assert.ShouldBeFalse(match("0123456789"))
|
||||
}
|
||||
|
||||
func TestPredicatesXnorPure(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := internal.NewAssert(t, "TestPredicatesXnorPure")
|
||||
|
||||
isEven := func(i int) bool { return i%2 == 0 }
|
||||
isPositive := func(i int) bool { return i > 0 }
|
||||
|
||||
match := Xnor(isEven, isPositive)
|
||||
|
||||
assert.ShouldBeTrue(match(2))
|
||||
assert.ShouldBeTrue(match(-3))
|
||||
assert.ShouldBeFalse(match(3))
|
||||
}
|
||||
|
||||
func TestPredicatesMix(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -95,4 +110,7 @@ func TestPredicatesMix(t *testing.T) {
|
||||
|
||||
c = Nor(a, b)
|
||||
assert.ShouldBeFalse(c("hello!"))
|
||||
|
||||
c = Xnor(a, b)
|
||||
assert.ShouldBeTrue(c("hello!"))
|
||||
}
|
||||
|
Reference in New Issue
Block a user