LINQ获取列表中的不同计数/排序<list <string>&gt;

时间:2017-06-24 14:55:21

标签: c# linq

我的List<>包含List<string>,其中我需要确定List<string中的唯一计数,并按计数的频率排序。

示例:

  • &#34;&#34;&#34; B&#34;&#34; C&#34;
  • &#34; d&#34;&#34; E&#34;&#34; F&#34;
  • &#34;&#34;&#34; B&#34;
  • &#34; a&#34;,&#34; b&#34;,&#34; c&#34;
  • &#34; a&#34;,&#34; b&#34;,&#34; c&#34;
  • &#34;&#34;&#34; B&#34;

这将输出(排名/组合/频率)

  • 1 - &#34; a&#34;,&#34; b&#34;,&#34; c&#34; - 3
  • 2 - &#34; a&#34;,&#34; b&#34; - 2
  • 3&#34; d&#34;,&#34; e&#34;,&#34; f&#34; - 1

我可以提出一种蛮力的方法,但是这可以用LINQ更优雅地完成吗?从我所知道的来看,这并不是笛卡尔式的方法。

感谢。

1 个答案:

答案 0 :(得分:2)

您可以编写自己的IEqualityComparer并将其与GroupBy一起使用。

public class StringArrayValueComparer : IEqualityComparer<List<string>>
{
    public bool Equals(List<string> x, List<string> y)
        => x.SequenceEqual(y);

    public int GetHashCode(List<string> obj)
        => obj.Aggregate(1, (current, s) => current * 31 + s.GetHashCode());
}

var list = new List<List<string>>(new[]
{
    new List<string>(new [] { "a","b","c" }),
    new List<string>(new [] { "d","e","f" }),
    new List<string>(new [] { "a","b" }),
    new List<string>(new [] { "a", "b", "c" }),
    new List<string>(new [] { "a", "b", "c" }),
    new List<string>(new [] {"a","b"})
});

var orderedList = list
    .GroupBy(x => x, x => x, (x, enumerable) => new { Key = x, Count = enumerable.Count()}, new StringArrayValueComparer())
    .OrderByDescending(x => x.Count)
    .Select((x, index) => new { Rank = index + 1, Combination = x.Key, Frequency = x.Count });

foreach (var entry in orderedList)
{
    Console.WriteLine($"{entry.Rank} - {string.Join(",", entry.Combination)} - {entry.Frequency}");
}
  

1 - a,b,c - 3

     

2 - a,b - 2

     

3 - d,e,f - 1