![](/img/trans.png)
[英]LINQ Query to Count Objects by Property Group Between Non Group Objects In Sequence
[英]LINQ group by sequence and count with sorting
我正在尋找一種使用LINQ進行排序的最佳性能方法,以對序列進行分組和計數。 我將處理甚至超過500 MB的文件,因此性能是該任務中最重要的關鍵。
List<int[]> num2 = new List<int[]>();
num2.Add(new int[] { 35, 44 });
num2.Add(new int[] { 200, 22 });
num2.Add(new int[] { 35, 33 });
num2.Add(new int[] { 35, 44 });
num2.Add(new int[] { 3967, 11 });
num2.Add(new int[] { 200, 22 });
num2.Add(new int[] { 200, 2 });
結果必須是這樣的:
[35, 44] => 2
[200, 22] => 2
[35, 33] => 1
[35, 44] => 1
[3967, 11] => 1
[200, 2 ] => 1
我做了這樣的事情:
Dictionary<int[], int> result2 = (from i in num2
group i by i into g
orderby g.Count() descending
select new { Key = g.Key, Freq = g.Count() })
.ToDictionary(x => x.Key, x => x.Freq);
SetRichTextBox("\n\n Second grouping\n");
foreach (var i in result2)
{
SetRichTextBox("\nKey: ");
foreach (var r in i.Key)
{
SetRichTextBox(r.ToString() + " ");
}
SetRichTextBox("\n Value: " + i.Value.ToString());
}
但是它不能正常工作。 有什么幫助嗎?
對於長度為2的數組,這將起作用。
num2.GroupBy(a => a[0])
.Select(g => new { A0 = g.Key, A1 = g.GroupBy(a => a[1]) })
.SelectMany(a => a.A1.Select(a1 => new { Pair = new int[] { a.A0, a1.Key }, Count = a1.Count() }));
我認為這應該為您提供最佳性能; 您還可以在第一個Select語句之后嘗試.AsParallel()
子句。
此策略(按數組的第n個元素連續分組)概括為任意長度的數組:
var dim = 2;
var tuples = num2.GroupBy(a => a[0])
.Select(g => new Tuple<int[], List<int[]>>(new [] { g.Count(), g.Key }, g.Select(a => a.Skip(1).ToArray()).ToList()));
for (int n = 1; n < dim; n++)
{
tuples = tuples.SelectMany(t => t.Item2.GroupBy(list => list[0])
.Select(g => new Tuple<int[], List<int[]>>(new[] { g.Count() }.Concat(t.Item1.Skip(1)).Concat(new [] { g.Key }).ToArray(), g.Select(a => a.Skip(1).ToArray()).ToList())));
}
var output = tuples.Select(t => new { Arr = string.Join(",", t.Item1.Skip(1)), Count = t.Item1[0] })
.OrderByDescending(o => o.Count)
.ToList();
產生一個輸出
Arr = "35, 44", Count = 2
Arr = "200, 22", Count = 2
Arr = "35, 33", Count = 1
Arr = "200, 2", Count = 1
Arr = "3967, 11", Count = 1
在您的示例中。 我讓您對其進行更大尺寸的測試。 :)
您應該能夠毫不費力地並行化這些查詢,因為后續分組是獨立的。
您可以執行以下操作:
var results = from x in nums
group x by new { a = x[0], b = x[1] } into g
orderby g.Count() descending
select new
{
Key = g.Key,
Count = g.Count()
};
foreach (var result in results)
Console.WriteLine(String.Format("[{0},{1}]=>{2}", result.Key.a, result.Key.b, result.Count));
訣竅是想出一種比較數組中的值而不是數組本身的方法。
另一種選擇(可能是更好的選擇)是將數據從int[]
為某種自定義類型,覆蓋該自定義類型上的相等運算符,然后將group x by x into g
,但是如果您確實對int[]
感到int[]
然后這個工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.