1

I have an array of numbers, I'm trying to see the value of the numbers that occur 3 times in the array. For example here is an array of numbers [4, 4, 4, 3, 3] and when I pass this into this query as dice:

var triples = dice.GroupBy(x => x).Where(g => g.Count() > 2).Select(y => y.Key);

I can see in the results view of the triples object a 4 which is what I want but how do I pull that number out and into a variable to use? I don't understand LINQ that well yet. Thanks!

Right now I get object of type: System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<int,int>,int> as the value of triples, and when I dive into the object I can see the value that I want "4" in the results view

Adam Weitzman
  • 1,402
  • 4
  • 17
  • 43
  • What do you mean into a variable to use? You have it in `triples`. It is an `IEnumerable` containing all those numbers that occurred 3 or more times. What do you want to do with it? – Gilad Green Oct 03 '16 at 20:53
  • right now I get {System.Linq.Enumerable.WhereSelectEnumerableIterator,int>} – Adam Weitzman Oct 03 '16 at 20:54
  • I want to put the value into a variable – Adam Weitzman Oct 03 '16 at 20:55
  • 1
    Possible duplicate of [How to convert LINQ query result to List?](http://stackoverflow.com/questions/10333619/how-to-convert-linq-query-result-to-list) – Amit Oct 03 '16 at 20:55

3 Answers3

1

If you need to get first number what occurs at least 3 times use First() extension method

var firstTriple = dice.Where(...).First();

or Single if you want to make sure it's only one item, otherwise throw an exception.

If you need an Array

var triples = dice.Where(...).ToArray()

Your initial query doesn't filter any values until you fetch data (call ToArray(), First(), iterate using foreach).

var query = dice.Where(...); // not executed
query = query.GroupBy(...);  // not executed
query = query.Select(...);   // not executed
query = query.OrderBy();     // not executed
var result = query.ToArray();// executed only at this moment;
// or in foreach loop
foreach(var item in query){  // 
   //
}
Artiom
  • 7,021
  • 3
  • 34
  • 43
1

Add ToList/ToArray/First/FirstOrDefault:

var triples = dice.GroupBy(x => x)
                  .Where(g => g.Count() > 2)
                  .Select(y => y.Key)
                  .ToList();

Most of linq methods are differed executed - meaning that they are not executed at the line they are written at but only when a concrete result is needed. The happens when calling a method like: ToList/ToArray/First/FirstOrDefault/Sum/Count...

Without the ToList above what you see is the "execution plan" of that linq and when pressing the "Result View" it actually executes it.

In your normal flow of the code you will probably at some point actually use the triples (for instance in a foreach loop to print to the console) and then it will be executed.


Here is a code snippet to explain the above. Put break-points in the foreach and in the Select and run it once the wat it is now and once with a ToList() and see the difference.

List<int> data = new List<int> { 1, 1, 1, 2, 2, 3, 3, 3, 4 };

var triples = data.GroupBy(x => x)
                  .Where(g => g.Count() > 2)
                  .Select(y => y.Key); // put breakpoint here

foreach(var item in triples) //Put breakpoint here
{
   Debug.Write(item);
}

For more, read LINQ and Deferred Execution

Gilad Green
  • 34,248
  • 6
  • 46
  • 76
0
var firstTriple = triples.FirstOrDefault();

Plain and simple.

Adrian Iftode
  • 14,740
  • 3
  • 41
  • 71