-1

According to this thread Elegantly determine if more than one boolean is "true"

using this part of code...

public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{
   int trueCnt = 0;
   foreach(bool b in bools)
      if (b && (++trueCnt > threshold)) 
          ***//here i need to know which of b is the true***
          return true;
   return false;          
} 

I want to know which of bools variable is true?

Community
  • 1
  • 1
greg dorian
  • 136
  • 1
  • 3
  • 14
  • 1
    I'm not sure I understand the question. When you say you want to know which of the boolean variables is true do you mean the indices (for example: index 1, 3 and 4 are true)? – chrischu Jul 10 '13 at 13:30
  • What do you mean with `which one is true`. Strictly speaking, `IEnumerable` does not guarantee order, so retrieving the indexes of true or false values is not right. As I see it, the only information you can get from the `IEnumerable` is a count of true, false and total values, and nothing else. – KekuSemau Jul 10 '13 at 13:30
  • Yes Chrischu and quetzacotel using ElementAt or another method that show me a list or single element that is true – greg dorian Jul 10 '13 at 13:42
  • @KekuSemau An `IEnumerable` most certainly *is* ordered. What would give you the impression that it's not. – Servy Jul 10 '13 at 13:52
  • 1
    This smells of object denial; What are you going to do with the indexes? Look up some other value in another list? – weston Jul 10 '13 at 14:44
  • @Servy I had been looking at the arguments here http://stackoverflow.com/questions/10409893/ienumerable-and-order - accepted answer and second comment for a start. As in that answer, I'll agree that only the interface does not guarantee it, while some objects passed may well be ordered. That may be enough in real life situations. – KekuSemau Jul 10 '13 at 15:49
  • @KekuSemau Items in an `IEnumerator` *are* ordered. Something comes out first, and something else comes out second, and so on. It's not "not ordered". Now, that order may or may not mean something, just like the items in a `List` might have a meaningful order, or they could be in some arbitrary order, but the key is that they *still have an order*, unlike, for example, a `HashSet`, for which the items simply have no order. The OP is specifically asking for the indexes, and that's something that you most certainly can do. Whether that's useful or not depends on the source sequence. – Servy Jul 10 '13 at 15:52

7 Answers7

7

If you want to know the indices of the true values, use the overload of Select that includes an index parameter:

IList<int> indices = bools.Select((b, i) => new {Index = i, IsTrue = b})
                          .Where(x => x.IsTrue)
                          .Select(x => x.Index)
                          .ToList();
D Stanley
  • 149,601
  • 11
  • 178
  • 240
2

Given a list of bool, this will return a list of the indexes that are true:

var myList = new List<bool>{false, false, true, true, false};

// Will return an IEnumerable containing {2, 3}:
var trueStuff = myList.Select((value, pos) => pos).Where(pos => myList[pos]);

Update: As pointed out in the comment below, the above would only work for a List, and not for an IEnumerable. I'll still leave it here though, as it may be useful in another similar situation.

Also, just for the record, here's a solution (albeit a slightly less elegant one) that should work in either case:

// Note: IEnumerable this time:
IEnumerable<bool> myList = new List<bool> { false, false, true, true, false };

var trueStuff = new List<int>();
int pos = 0;
foreach (var b in myList)
{
    if(b){ trueStuff.Add(pos); }
    pos++;
}
Kjartan
  • 18,591
  • 15
  • 71
  • 96
  • I can see I've currently got one up-vote, and one down-vote for this. That is fine, but I would appreciate a comment explaining the reason for the latter.. – Kjartan Jul 10 '13 at 14:00
  • The input is an `IEnumerable`, not a `List`. You shouldn't be indexing into an `IEnumerable`, making this not an appropriate solution. – Servy Jul 10 '13 at 14:01
  • You're right... Doh! I made some changes, thanks for the input! – Kjartan Jul 10 '13 at 14:28
1

I want to know which of bools variable is true?

this one uses LINQ

IList<bool> _result = bools.Where(x => x == true);
John Woo
  • 258,903
  • 69
  • 498
  • 492
  • 6
    Won't this simply give you a list of some amount of `true`s? It might be worth more with for example the indexes of the elements that are `true`. – Magnus Hoff Jul 10 '13 at 13:26
  • yes! magnus that is! how do I do to obtain the indexes of the elements that are true – greg dorian Jul 10 '13 at 13:35
  • 1
    @gregdorian You start by including such a requirement in the question, rather than having people try to guess what you want the result to be. – Servy Jul 10 '13 at 13:52
1

I'm not sure if I am understanding this correctly, but if you wanted to know which Boolean values in an enumerated list are true and which ones are false, you could modify that routine to be something like this:

public static string GetBoolString(IEnumerable<bool> bools) 
{
  var boolArray = bools.ToArray();
  char[] data = new char[boolArray.Length];
  for (int i = 0; i < boolArray.Length; i++)
  {
    data[i] = boolArray[i] ? '1' : '0';
  }
  return new string(data);
}

Note that I am not presenting any "elegant" solution; just getting it done.

-1

If you switch from IEnumerable to something with an inbuilt index (like an array or List), you can do this, to return a list of the indices that are true:

public IEnumerable<int> GetTrueIndices(bool[] b)
{
    return Enumerable.Range(0, b.Length).Where(i => b[i]);
}

with a list it would be this:

public IEnumerable<int> GetTrueIndices(List<bool> b)
{
    return Enumerable.Range(0, b.Count).Where(i => b[i]);
}
Dan Puzey
  • 33,626
  • 4
  • 73
  • 96
  • Your implementation for the case of `IEnumerable`, which is the case the OP has, is horribly inefficient. You iterate the sequence N+1 times (where once is enough). That's...*really* bad. – Servy Jul 10 '13 at 13:54
  • I did say it wasn't performant - I only included the IEnumerable case for reference. Since (as others hqave pointed out) there's no real ordering guaranteed in an `IEnumerable` anyway, I'd say that my first suggestion is probably the best answer to the question. – Dan Puzey Jul 10 '13 at 14:00
  • And yet it's the case that matters; the other two aren't relevant as they're not what the OP is dealing with. Also it's not just a performance issue; you cannot rely on the fact that you'll be *able* to iterate an arbitrary sequence multiple times, or that it will have the same values if you do. – Servy Jul 10 '13 at 14:02
  • Equally you can't rely on indices being the same for two iterations of an `IEnumerable`; there's no guarantee that the current highest voted answer will return anything *meaningful*. Answering the question sometimes means correcting invalid assumptions. I've removed the `IEnumerable` version, anyway. – Dan Puzey Jul 10 '13 at 14:10
  • That it won't be the same if called twice doesn't mean you can't meaningfully use it. The function should iterate it no more than once, and should return the indexes for that one iteration. If the result sequence is iterated multiple times it could reflect changes in the source sequence, or the fact that it is different when iterated multiple times. That doesn't make such a method invalid. What it means is that you should only iterate the sequence exactly once, which is more than possible to do. Now your answer doesn't answer the question as you're not using the input the OP has. – Servy Jul 10 '13 at 14:13
-1
var firsttrue = bools.First(b => b);
Marko Juvančič
  • 5,792
  • 1
  • 25
  • 41
-2

Don't use IEnumerable if you want to work with indices, but use arrays.

To get indices use for loop and iterate over the array.

Felix C
  • 1,755
  • 5
  • 26
  • 40
  • Linq has method overloads that let you get the index of each item. – D Stanley Jul 10 '13 at 13:42
  • But the OP did not ask for a LINQ solution, so why downvoting the ordinary way which is language independent? – Felix C Jul 10 '13 at 13:53
  • @FelixC Because you said it *can't* be done with an `IEnumerable` and that he needs to use a `for` loop. He doesn't. He most certainly *can* do this using an `IEnumerable`. He doesn't need to us LINQ, that's true. If you want to show a non-LINQ solution that's fine, but saying that you *must* convert the `IEnumerable` to an array is simply wrong. – Servy Jul 10 '13 at 13:55
  • I never said that it is not possible, I said he should not use it. `IEnumerable` does not guarantee the right order of the elements. – Felix C Jul 10 '13 at 13:58
  • @FelixC That's simply false. What's your basis for that assertion? – Servy Jul 10 '13 at 14:05