Reputation:
I have a list that contains strings and integers that have been converted to strings. I'm trying to write a LINQ query where the count of all distinct strings that arent an integer, e.g. "Hello", "Hi, "Greetings" etc and a count of all integers but that arent strings e.g.
List x = { "1", "6", "3", "Hi", "5", "Hello", "Hi" }
Output to be:
integer count = 4
Hi = 2
Hello = 1
I currently have the query grouping all that arent integers correctly however each integer is being listed distinctinvely e.g.
Hi count = 2 Hello count = 1 1 count = 1 6 count = 1 3 count = 1 5 count = 1
Here is my query so far :-(
var q = from x in output
group x by x into g
let count = g.Count()
orderby count descending
select new { Value = g.Key, Count = count };
I tried to have another loop count all values that arent Hi Hello etc.
var integerCount = q.Select(
x => x.Value != "Hi"
|| x.Value != "Hello")
.Count();
But that count seems to be incorrect. Is there anyway i Could do just the 1 query that returns what I want?
Thank you.
Upvotes: 2
Views: 1341
Reputation:
I've managed to refine some of the code above to get the result. But thank you all for your help.
var count = list.Aggregate(new { Integer = 0, Hi = 0, Hello = 0, (c, s) =>
{
int c1 = c.Integer,
c2 = c.Hi,
c3 = c.Hello,
n;
if (int.TryParse(s, out n))
c1++;
else if (s == "Hi")
c2++;
else if (s == "Hello")
c3++;
return new {
Integer = c1,
Hi = c2,
Hello = c3,
};
});
Upvotes: 0
Reputation: 12196
Steps:
List<string>
.int.TryParse
integers parse method to decide of the value is in type Integer or not.elem => elem
.Key: ElementValue, and Value: Count
from each group and the .Count
on that group.Code v1:
var list = new List<string> { "1", "6", "3", "Hi", "5", "Hello", "Hi" };
int num;
var integers = list.Where(elem => int.TryParse(elem, out num));
var strings = list.Where(elem => !int.TryParse(elem, out num));
var dictIntegers = integers.GroupBy(elem => elem).ToDictionary(elem => elem.Key, elem => elem.Count());
var dictStrings = strings.GroupBy(elem => elem).ToDictionary(elem => elem.Key, elem => elem.Count());
Code v2:
var list = new List<string> { "1", "6", "3", "Hi", "5", "Hello", "Hi" };
int num;
var listGroupedByElement = list.GroupBy(elem => elem).ToDictionary(elem => elem.Key, elem => elem.Count());
var dictIntegers = listGroupedByElement.Where(elem => int.TryParse(elem.Key, out num));
var dictStrings = listGroupedByElement.Where(elem => !int.TryParse(elem.Key, out num));
Upvotes: 0
Reputation: 205889
Here you go:
var counts = list.Aggregate(new { Integer = 0, Other = 0 }, (c, s) =>
{
int c1 = c.Integer, c2 = c.Other, n;
if (int.TryParse(s, out n)) c1++; else c2++;
return new { Integer = c1, Other = c2 };
});
Debug.Print("Integers:{0} Other:{1}", counts.Integer, counts.Other);
Upvotes: 1
Reputation: 1288
List<string> items = { "1", "6", "3", "Hi", "5", "Hello", "Hi" };
var result = items.Select(x => new {
IsInt = Int32.TryParse(x),
TextValue = x
});
var integerCount = result.Where(x => x.IsInt).Count();
var countPerText = result.Where(x => !x.IsInt)
.GroupeBy(x => x.TextValue)
.Select(group => new {
Text = group.Key,
Count = group.Count()
});
Upvotes: 0