我有一個類
public class Test
{
public string name;
public int status;
}
示例資料
new Test("Name1", 1);
new Test("Name2", 2);
new Test("Name3", 3);
new Test("Name4", 1);
new Test("Name5", 2);
new Test("Name6", 2);
new Test("Name7", 3);
我正在尋找一些 linq 來回傳值 2 - 這是最常出現的狀態。
目前我有以下不正確的。
var status = listTest.GroupBy(x => x.status).Select(x => x.OrderByDescending(t => t.status).First()).FirstOrDefault().status;
但希望有更清潔的東西嗎?
uj5u.com熱心網友回復:
我想這就是你想要的
您需要對組本身進行排序,而不是對每個組中的內容進行排序。
var status = listTest
.GroupBy(x => x.Status)
.OrderByDescending(g => g.Count())
.FirstOrDefault()?.Key;
uj5u.com熱心網友回復:
您可以在降序排序后分組并選擇頂部
var value = list.GroupBy(q => q.status)
.OrderByDescending(gp => gp.Count())
.First().Key;
uj5u.com熱心網友回復:
要求:給定一系列 class 物件
Test,其中每個 Test 都有一個 int 屬性Status,給我出現最多的 Status 值。
為此,使組測驗物件具有相同的屬性狀態值。計算每組中元素的數量。對結果進行排序,使得具有最大數量的組在前,并取第一個元素。
IEnumerable<Test> testSequence = ...
var statusThatOccursMost = testSequence
// make Groups of Tests that have the same value for Status:
.GroupBy(test => test.Status,
// parameter resultSelector: for every occurring Status value and all
// Tests with this common status value, make one new object,
// containing the common Status value and the number of Tests that have
// this common Status value
(commonStatusValue, testsThatHaveThisCommonStatusValue) => new
{
Status = commonStatusValue,
Count = testsThatHaveThisCommonStatusValue.Count(),
})
結果:一系列 [Status, Count] 組合。Status 在 testSequence 中至少出現一次。Count 是 Status 出現的次數。所以我們知道,Count >= 1。
按 Count 值的降序對 [Status, Count] 組合序列進行排序,因此第一個元素是 Count 值最大的元素:
.OrderByDescenting(statusCountCombination => statusCountCombination.Count)
結果:一系列 [Status, Count] 組合,其中 Count 值最大的組合在前。
從組合中提取 Status 的值,并取第一個:
.Select(statusCountCombination => statusCountCombination.Status)
.FirstOrDefault();
優化
盡管此 LINQ 相當簡單,但如果您只想要 Count 具有最大值的組合,則計算所有 Status 值并對所有 StatusCount 組合進行排序并不是很有效。
考慮創建一個擴展方法。如果您不熟悉擴展方法,請閱讀擴展方法揭秘
制作字典:關鍵是狀態。值是此狀態發生的次數。然后取Count最大的Status
public static int ToMostOccuringStatusValueOrDefault(
this IEnumerable<Test> testSequence)
{
// return default if testSequence is empty
if (!testSequence.Any()) return 0;
Dictionary<int, int> statusCountCombinations = new Dictionary<int, int>();
foreach (Test test in testSequence)
{
if (statusCountCombinations.TryGetValue(test.Status, out int count)
{
// Status value already in dictionary: increase count:
statusCountCombinations[test.Status] = count 1;
}
else
{
// Status value not in dictionary yet. Add with count 1
statusCountCombinations.Add(test.Status, 1);
}
}
GroupBy 的作業方式與上面類似,不同之處在于它首先會創建一個字典,其中每個值都是一個測驗串列。然后如果計算Tests的數量,并丟棄串列。在擴展方法中,我們不必制作串列。
Continuing the extension method: find the KeyValuePair that has the largest Value. We can use Enumerable.Aggregate, or enumerate:
using (var enumerator = statusCountCombinations.GetEnumerator())
{
// we know there is at least one element
enumerator.MoveNext();
// the first element is the largest until now:
KeyValuePair<int, int> largest = enumerator.Current;
// enumerate the rest:
while (enumerator.MoveNext)
{
if (enumerator.Current.Value > largest.Value)
{
// found a new largest one
largest = enumerator.Current;
}
}
return largest.Key;
}
}
In this method we only have to enumerate testSequence once, and your Dictionary once. If you would use Linq GroupBy / OrderByDescending, the result of GroupBy would be enumerated several times
Usage:
IEnumerable<Test> testSequence = ...
var mostCommonStatus = testSequence.ToMostOccurringStatusValueOrDefault();
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/318195.html
