Reputation: 9658
I have a list of a list of strings:
List<List<String>> pChain;
It might have repeated lists of strings (two list of strings are equal if they have the same strings in the same order). I want to have the count of each distinct list in the main list. I tried:
var results = (from t in pChain
group t by new { t }
into g
select new
{
g.Key,
Count = g.Count(),
}).OrderByDescending(x => x.Count).ToList();
foreach (var v in results)
{
ListViewItem lv = listView2.Items.Add(v.Key.ToString());
lv.SubItems.Add(v.Count + "");
}
But it doesn't group similar list of strings into one list and doesn't count them.
Upvotes: 0
Views: 101
Reputation: 9658
I tried Aggregate
function to join the strings of the inner list to a string resulted from concatenating them. Then applied the GroupBy
to this list.
Dictionary<string, int> itemCounts =
pChain.Select(list => list.Aggregate((i, j) => j + '/' + i))
.GroupBy(item => item).OrderByDescending(x => x.Key)
.ToDictionary(g => g.Key.ToString(), g => g.Count());
foreach (var v in itemCounts)
{
ListViewItem lv = listView2.Items.Add(v.Key.ToString());
lv.SubItems.Add(v.Value + "");
}
Upvotes: 0
Reputation: 3576
You can check if a list of lists contains an specific list by iterating through its elements and checking if they are SequenceEqual(). You should be able to remove the duplicate lists with this:
for(int i = 0; i < pChain.Count(); i++)
{
// If the amount(Count) of SequenceEqual lists in pChain for the current iteration
// of pChain (pChain[i]) is > 1
if (pChain.Count(l => l.SequenceEqual(pChain[i])) > 1)
pChain.RemoveAt(i);
}
Thus the amount of distinct lists would be:
int count = pChain.Count();
You can put the code above into a single linQ line this way:
pChain.Select((x, y) => new { list = x, Index = y }).ToList()
.ForEach(l1 => {
if (pChain.Count(l2 => l2.SequenceEqual(l1.list)) > 1)
pChain.RemoveAt(l1.Index);
});
Upvotes: 1
Reputation: 460158
You can use SelectMany
+ Distinct
:
var allDistinctItems = pChain.SelectMany(list => list).Distinct();
If you want the count use int countOfDistinctItems = allDistinctItems.Count();
.
If you want a dictionary you could use:
Dictionary<string, int> itemCounts = pChain.SelectMany(list => list)
.GroupBy(item => item)
.ToDictionary(g => g.Key, g => g.Count());
Upvotes: 6