In this scenario I have 3x boolean vars (already set to either true
or false
)
The goal here is to identify if more than one of the set of bool vars are set to true
Right now I have the following written, which does work:
boolval := 0
if *firstbool {
boolval++
}
if *secondbool {
boolval++
}
if *thirdbool {
boolval++
}
if boolval > 1 {
// More than 1 of the bool vars are true
}
I always flag my logic if I am writing successive if{}
statements, so I figured I would ask you geniuses how you would accomplish this.
identify if more than one of the set of bool vars are set to true
For example, write a set function:
package main
import "fmt"
func nTrue(b ...bool) int {
n := 0
for _, v := range b {
if v {
n++
}
}
return n
}
func main() {
v1, v2, v3 := true, false, true
fmt.Println(nTrue(v1, v2, v3))
if nTrue(v1, v2, v3) > 1 {
// . . .
}
// Or
if n := nTrue(v1, v2, v3); n > 1 {
// . . .
}
// Or
n := nTrue(v1, v2, v3)
if n > 1 {
// . . .
}
}
Playground: https://play.golang.org/p/g3WCN6BgGly
Output:
2
For example, range over the set,
package main
import "fmt"
func main() {
v1, v2, v3 := true, false, true
boolval := 0
for _, v := range []bool{v1, v2, v3} {
if v {
boolval++
}
}
if boolval > 1 {
// . . .
}
fmt.Println(boolval > 1, boolval)
}
Playground: https://play.golang.org/p/R6UGb8YYEFw
Output:
true 2
Depending on how you're getting the values of firstbool
et. al, there might be a more idiomatic approach you should take here. Consider that channels and goroutines can handle doing the accounting in the background. If your booleans are the result of some heavier operations, it might make sense to do something like:
package main
import "fmt"
func firstFunc(ch chan bool) {
// assume this works, true!
ch <- true
}
func secondFunc(ch chan bool) {
// assume this fails, false!
ch <- false
}
func thirdFunc(ch chan bool) {
// assume this works, true!
ch <- true
}
func listener(ch chan bool, numCallers int) <-chan bool {
outch := make(chan bool)
THRESHOLD := 2
go func(outch chan<- bool) {
count := 0
trues := 0
for count < numCallers && trues < THRESHOLD {
val := <-ch
if val {
trues++
}
count++
}
outch <- trues >= THRESHOLD
}(outch)
return outch
}
func main() {
ch := make(chan bool)
resultch := listener(ch, 3)
go firstFunc(ch)
go secondFunc(ch)
go thirdFunc(ch)
if <-resultch {
fmt.Println("Two or more processes succeeded")
}
}
However this is way over-engineered for a simple need, so consider this only if this pattern fits the larger design of your application.
Maybe I'm tragically misunderstand something but this question is looks like exercise in boolean algebra.
The goal here is to identify if more than one of the set of bool vars are set to true
So "sum" actually means: "more than once or "twice or more"
func MoreThanOnce(a, b, c bool) bool {
return (
a&&(b||c)) ||
(a||b)&&c ||
(a||c)&&b
}
func MoreThanOnce(a, b, c bool) bool { return a&&b || a&&c || b&&c}
One line, no if
s, no channels, no pointers.
Is this what was wanted?
UPDATE
From @peterSO comment:
In the example, there are three successive if statements. Perhaps there are four, or seven, or forty-two successive if statements. How would you sum those examples?
func MoreThanOnce(vs...bool) (result bool){
for i:=0; i<len(vs); i++{
for j:=i+1; j<len(vs); j++{
if i!=j{ // this `if` could be omitted
result = result || vs[i] && vs[j]
}
}
}
return
}
Is this what was asked?