如何List<object>對物件始終所在的位置進行排序List<string>。我知道已經存在與此類似的問題。我嘗試了 Sort() 或其他建議的功能,但無法解決。
這就是我所擁有的:
var result= new List<object>();
foreach (var data in myData)
{
result.Add(new List<string>() { data.Text, myData.Count().ToString() });
}
//This is how at the end the List<object> looks like:
[
[
"xxx",
"2"
],
[
"xxxx",
"2"
],
[
"xxx",
"2"
],
[
"xxxx",
"3"
],
[
"xxx",
"48"
],
[
"xxxx"
"18"
],
[
"xxxx",
"58"
],
[
"xxxx",
"1"
],
[
"xxxx",
"371"
],
[
"xxxx",
"3"
],
[
"xxxxx",
"2"
]
]
我需要按List<object>串列的第二個元素排序,它總是數字
uj5u.com熱心網友回復:
您可以像這樣對串列進行排序:
data = data.OrderBy(i => int.Parse(i[1])).ToList();
但是,如果我們跳過問題中的中間步驟,我們可以做得更好,并從以下開始myData:
var data = myData.Select(md => (md.Text, md.Count())).OrderBy(md => md.Item2);
這看起來與您要求的有點不同,但客觀上它更好,原因有兩個:
它使我們可以將
int值保持在更精確的型別中。由于國際化/文化問題,在數字或日期和字串之間來回轉換比我們想象的要慢得多,也更容易出錯。因此,這是要避免的。盡可能長時間地保留專門的數字資料通常要好得多,并且只在最后可能的時刻轉換為字串。在這種情況下,我們保存了兩次轉換操作(每個方向一次),所以這段代碼應該已經比原來的快得多了。我們最終得到一個
IEnumerable<(string, int)>,而不是一個List<List<string>>。IEnumerable<T>幾乎總是比 更有效,因為減少List<T>了記憶體使用和流資料的能力,而不是需要預先加載整個設定。
但是,我知道您可能需要以特定方式將資料傳遞到下一步。如果你真的需要 janky List<List<string>>,你可以這樣做:
var data = myData.OrderBy(md => md.Count()).
Select(md => new List<string>{md.Name, md.Count().ToString()}).
ToList();
請注意,由于上述幾點,即使我們真的想要串列,最有效的方法仍然是在創建最終串列之前保留原件int以進行訂購和制作IEnumerable,并且取決于運行Count()它可能需要多長時間甚至更有效地使用我的主要建議IEnumerable<(string, int)>作為中間步驟:
var data = myData.Select(md => (md.Text, md.Count())).
OrderBy(md => md.Item2).
Select(md => new List<string> {md.Item1, md.Item2.ToString()}).
ToList();
希望這也可以幫助您以不同的方式思考這種資料處理。如果帶有型別資料的 IEnumerable 效率更高,以至于我們無論如何都將其用作中間步驟,那么它可能也是首先處理在方法或類之間傳遞資料的更好方法。至少,您至少可以開始考慮.ToList()從這些行的末尾洗掉 ,因為在將變數傳遞給仍然確實需要串列的函式時,您總是可以將其附加到變數中。
uj5u.com熱心網友回復:
您可以使用方便的 C# ValueTuples以簡單的方式創建強型別資料。
var textCount = new List<(string Text, int Count)>();
foreach (var data in myData)
{
textCount.Add( (data.Text, data.Count()) );
}
// In-place sort of list
textCount.Sort((a, b) => a.Count.CompareTo(b.Count));
如果您想按降序排序,只需否定比較
textCount.Sort((a, b) => -a.Count.CompareTo(b.Count));
或將 b 與 a 進行比較:
textCount.Sort((a, b) => b.Count.CompareTo(a.Count));
或者使用 LINQ
var textCount = myData
.Select(d => (d.Text, Count: d.Count()))
.OrderBy(t => t.Count) // Use OrderByDescending for reverse sort
.ToList();
// Test
foreach (var item in textCount) {
Console.WriteLine($"Text = {item.Text}, Count = {item.Count}");
}
兩種解決方案都將計數存盤為int. 這對排序很重要。存盤為字串的數字將無法正確排序。你會得到一個字母順序,如“1”、“11”、“157”、“2”、“27”、“3”、“32”。
第二種解決方案的優點是在一個陳述句中創建元組、排序、創建和填充串列。
uj5u.com熱心網友回復:
我建議改用強型別結構,在這里使用的一個非常快速的結構可以是元組,它現在很好地集成到 C# 中 - 可以命名引數。或者甚至更好地創建一個適用于您使用的類。
無論您使用哪種結構,如果您真的想使用自定義邏輯對串列進行排序以比較物件,您可以將排序運算式作為引數提供給 Sort 方法。例如,如果您只關心第二個數字:
var result = new List<(string Text, int Count)>()
foreach (var data in myData)
{
result.Add(new ( data.Text, myData.Count()));
}
result.Sort((a,b) => a.Count - b.Count);
//here your list is already sorted
盡管公平地說,通常更希望的是不要觸摸原始實體并創建一個副本。您可以使用 LINQ 的 OrderBy 實作:
var sortedList = result.OrderBy((element) => element.Count)
這更簡潔,因為除非您需要處理更復雜的型別或執行計算,否則僅指示您的類的哪個屬性是用于排序的關鍵就足夠了。然后將按照鍵值指示的順序回傳物件,忽略類的其余部分。您還可以將更復雜的運算式作為第二個引數傳遞,類似于 Sort 方法。
uj5u.com熱心網友回復:
我認為您沒有理由在一開始就使用該物件,您可以執行以下功能
var result = new List<(string, string)>();
result.OrderBy(x => x.Item2);
這將使您可以輕松訂購并添加到這樣的串列中
foreach (var data in myData)
{
result.Add((data.Text, myData.Count().ToString()));
}
但是請注意,最好的方法是讓您通過數字索引對其進行排序,因此即使以這種方式,也不要將其轉換為字串,而是以數字方式使用它:
var result = new List<(string, int)>();
result.OrderBy(x => x.Item2);
foreach (var data in myData)
{
result.Add((data.Text, myData.Count().ToString()));
}
由于性能損失,我不建議僅將物件用作串列,如果我不得不考慮它,我將不得不創建一個抽象類來比較它們的串列并手動排序
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/513883.html
