1

I have a list of boolean values, what is the most efficient way to check if one of the boolean is true and all others are false?

For example, I have a array of 100 boolean values, how can I check if 1 boolean is true and all other booleans are false.

Venkat
  • 2,549
  • 2
  • 28
  • 61
Syamesh K
  • 826
  • 8
  • 18

9 Answers9

2

The author wants to know if only 1 value is Boolean

how can I check if 1 boolean is true and all other booleans are false.

in C# I would do something like

Suppose

List<bool> booleanList;

Then

int trueCount = booleanList.Count(b => b);
int falseCount = booleanList.Count(b => !b);
progrAmmar
  • 2,606
  • 4
  • 29
  • 58
  • +1, also OP stated he has list with 100 items co you really can just do `int falseCount = 100 - trueCount ` – svarog Oct 20 '16 at 07:30
  • Quite right. I just gave him both options he can go either way checking for true or false :) – progrAmmar Oct 20 '16 at 07:48
1

Iterate through the list and check each value. Stop if you find a second true value:

boolean found = false;
for (boolean b : list) {
  if (b) {
    if (found) return false;
    found = true;
  }
}
return found;

Alternatively, you can use List.indexOf and List.lastIndexOf:

int indexOfFirstTrue = list.indexOf(true);
return indexOfFirstTrue != -1 && list.lastIndexOf(true) != indexOfFirstTrue;
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Iterating through a large set of values will take a lot of time, I want to see if there is a easy method. – Syamesh K Oct 20 '16 at 07:19
  • If you want to check for exactly one true, there is nothing else you can do but iterate them. – Andy Turner Oct 20 '16 at 07:19
  • 1
    @SyameshK - `foreach` form of iteration [is the best performance you are gonna get](https://developer.android.com/training/articles/perf-tips.html#Loops) - I don't think you can do better that this. – Adrian Colomitchi Oct 20 '16 at 07:22
  • Nice use of `indexOf()`, you probably can't get any more efficient looking for a value in a list than `List`'s own implementation. – walen Oct 20 '16 at 08:57
1

Most performant way is to use BitSet instead of array:

BitSet set = new BitSet(100); // ~ boolean[] array = new boolean[100];
set.set(42); // ~ array[42] = true;
[...]
int countTrueBits = set.cardinality();

BitSet uses shift operations, so it is very fast.

Read more: boolean[] vs. BitSet: Which is more efficient?

Community
  • 1
  • 1
alex
  • 8,904
  • 6
  • 49
  • 75
  • is there any c# equivalent? – Syamesh K Oct 20 '16 at 07:24
  • @SyameshK Yes, BitArray: https://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx – alex Oct 20 '16 at 07:25
  • 1
    It may be true that it is most performant if you already have a bitset; but if you have a list (or array), converting to a `BitSet` takes more effort than just iterating the list (because it requires iterating the list, and then doing other stuff). – Andy Turner Oct 20 '16 at 07:47
  • @AndyTurner thats why I said "use BitSet instead of array". Convert array to BitSet is sure not a good idea. – alex Oct 20 '16 at 09:18
1

In C# using LinQ you can do it in single line of code

var check = itemList.Any(x => x.isActive == true);

It Will return true if any one model is active in the list.

Abinash
  • 471
  • 3
  • 13
0
 int countTrue=0;
for(boolean value: [Your List]){
     if(value)
       countTrue++;      

     if(countTrue>1) 
     break;  
 }

Check countTrue==1 OR not
Chandana Kumara
  • 2,485
  • 1
  • 22
  • 25
0

If you are working with Java 8 you can use this:

long size = booleanList.stream().filter(b -> Boolean.TRUE.equals(b)).count();
if(size == 1) {
    // do something
}
svarog
  • 9,477
  • 4
  • 61
  • 77
smsnheck
  • 1,563
  • 3
  • 21
  • 33
0

Using Java 8 streams

List<Boolean> bools = list.stream().filter(val -> false)
            .collect(Collectors.asList());

if (bools.size()==99) { ...}

You filter out all the values that are true. if your list has 100 values, you will receive a new list with 99 false values.

If you know you have only 1 true value in your list you can stop when you find it.

list.stream().filter(val -> true)
            .findFirst()
            .get();

It will get the first true value it encounters and returns it inside an Optional

svarog
  • 9,477
  • 4
  • 61
  • 77
  • That would always iterate over the whole list, thus being less efficient than a normal `for` loop for the 99.99% cases where more than 1 item is true and you could have finished the loop earlier. – walen Oct 20 '16 at 08:59
  • The second code is just wrong, because it doesn't check for more than 1 true value, which is what OP asked. If we're trying to know if there's only 1 true value, you cannot state "have only 1 true value" as prerequisite. – walen Oct 20 '16 at 09:02
  • OP asked `I have a array of 100 boolean values, how can I check if 1 boolean is true and all other booleans are false` to know this i will have to iterate over all values. that's what i'm doing in with the stream. I then count how much false values i'm getting from the `.filter` – svarog Oct 20 '16 at 09:05
  • I understand your code. But take this example: `{true, true, false, false, ... 95 more false ..., false}`. When you iterate over the list, by the time you read the second value you already know that there's more than 1 `true` value, you don't need to read the other 98 `false` values: you can return by iteration 2 instead of 100. And this applies to any of the `((2^n) - n - 1)` cases where there's more than 1 `true` value. A simple `for()` lets you do that. Your solution doesn't. – walen Oct 20 '16 at 09:47
  • right, that's way i stated `If you know you have only 1 true value in your list`. if you know you have multiple and you don't know how much, then you can't really do anything but count all of them. with the first code, you can get the count of the original list and a list with all the `false`s – svarog Oct 20 '16 at 10:36
0
int countTrue=0;
for(boolean value: [Your List]){
 if(value){
   countTrue++;  
   if(countTrue>1){
     // true is more than one time
     break;
   } 
  }

}
Prashanth Debbadwar
  • 1,047
  • 18
  • 33
0

I used IEnumerable.Count(Func) from System.Linq, with T as bool

bool[] values = {true, false, false, false};
int trueCount = values.Count(b=> b);

This will you the number of 'true' values in the list

Syamesh K
  • 826
  • 8
  • 18