Reputation: 48177
I have an array of integers. I can GroupBy
, Sort
, and Take
the less repeat element:
int [] list = new int[] {0, 1, 1, 0, 2};
var result = list
.GroupBy(a => a)
.Select(g => new {
Number = g.Key,
Total = g.Count()
})
.OrderBy(g => g.Total).Take(1);
Inside a foreach
I can retrieve the result, I even have Intellisense for group properties {Number, Total}
foreach (var group in result)
{
// Display key and its values.
Console.WriteLine("Number = {0} Total: {1}", group.Number, group.Total);
}
But I don't like to do a foreach
to do that, I prefer to do something like
result.Number or
result[0].Number
But doesn't work. What should be the right way to do it?
Upvotes: 0
Views: 108
Reputation: 23927
An anonymous type does not implement IEnumerable<T>
, there for you cannot access it via index.
If you only want the very first object you can use First()
or FirstOrDefault
. If you cast it to an array, you can use an index and then have support for your properties again:
result.FirstOrDefault().Number;
result.ToArray()[1].Number;
Upvotes: 1
Reputation: 21795
Your problem is that Take returns IEnumerable
, so if you want to fetch only first element, in that case use FirstOrDefault:-
var result = list.GroupBy(a => a)
.Select(g => new
{
Number = g.Key,
Total = g.Count()
})
.OrderBy(g => g.Total).FirstOrDefault();
Then, you can simply say: - result.Number
. Please note FirstOrDefault
may return null so better check for nulls before accessing any property otherwise you may get Null Reference Exception
.
Also, if you are looking for any specific index then you can use ElementAtOrDefault like this:-
var result = list.GroupBy(.....)..OrderBy(g => g.Total);
int SecondNumber = result.result.ElementAtOrDefault(1).Number;
But again be aware of NRE
.
Upvotes: 2
Reputation: 3431
Check these Methods:
.FirstOrDefault(); //gets the first element
.Take(n); //gets the first n elements
.Skip(n).FirstOrDefault(); //gets the (n+1)th element
.Skip(n).Take(m); //gets the first m elements after n elements
Upvotes: 1
Reputation: 141588
You are using Take(1)
which still returns an IEnumerable
. You probably want to use FirstOrDefault()
which does not return an IEnumerable.
.OrderBy(g => g.Total).Take(1);
Then you can use it like result.Number
and result.Total
.
Upvotes: 2