I have this code fragment:
List<string[]> list = new List<string[]>();
list.Add(new string[] { "A", "q", "t" });
list.Add(new string[] { "B", "w", "t" });
list.Add(new string[] { "B", "e", "r" });
list.Add(new string[] { "A", "r", "t" });
list.Add(new string[] { "B", "t", "e" });
var result = from item in list
group item by item[0] into g
let count = g.Count()
orderby count descending
select new { Value = g.Key, Count = count};
foreach (var res in result)
{
Console.WriteLine("Value: " + res.Value + " Count: " + res.Count);
}
that product this result:
Value: B Count: 3
Value: A Count: 2
How can I get this result without too many foreach?
Values: A q t - Count 2
Values: A r t - Count 2
Values: B w t - Count 3
Values: B e r - Count 3
Values: B t e - Count 3
You could do the following
var result = list.GroupBy(innerArray => innerArray[0])
.SelectMany(
grp => grp.Select(innerArray => new
{
Values = innerArray,
Count = grp.Count()
}));
foreach(var r in results)
{
Console.WriteLine("Values: {0} - Count {1}", string.Join(" ", r.Values), r.Count);
}
This first groups by the first item of each array then uses SelectMany
to flatten each group back into the original arrays and include the count.
This produces the exact order as your request, which might be a coincidence of your data. You can throw a OrderBy(g=>g.Count())
in there if you want to make sure it does a ascending order by the count.
The trick is fto use a SelectMany
var result = list.GroupBy(x=> x[0])
.SelectMany(x=> x,
(x,xx)=> new {
Value=string.Join(" ",xx),
Count = x.Count()
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.