假設我們有一個字串串列var listA = new List<string> {"B", "C", "A"},并以所需的方式對其進行排序。而且,有一個物件定義如下:
public class Sample {
public string Letter {get;set;} // "A","B","C","D","#"
public string Number {get;set;} // not relevant
}
另外,還有另一個串列,List<Sample> listB我想以一種方式對它進行排序,首先是具有字母值“B”的物件,然后是“C”,最后是“A”,因此要尊重與它相同的順序串列A。有任何想法嗎?:)
編輯: Letter 屬性可以有更廣泛的字符,不像 listA 可以只有這 3 個字符。預期順序“B”、“C”、“A”...“其余的,順序不相關”
uj5u.com熱心網友回復:
假設 的值在Letter范圍內listA。如果假設不成立,則值得考慮重新設計演算法。它可能取決于超出范圍的預期訂單的要求。
var sortedSamples = listB.OrderBy(x=>listA.IndexOf(x.Letter));
為了獲得更好的性能,請將訂單快取到字典中:
var orders = new Dictionary<string, int>();
for (int i = 0; i < listA.Count; i )
{
orders.Add(listA[i], i);
}
var sortedSamples = listB.OrderBy(x=>orders[x.Letter]);
如果可能的值范圍Letter遠小于listA,則更好的構造orders如下:
foreach (string letter in listB.Select(x=>x.Letter))
{
orders.Add(letter, listA.IndexOf(letter));
}
更新
如果letters' 范圍超出listA,并且由于 OP 希望 out 位于末尾:
var orders = new Dictionary<string, int>();
for (int i = 0; i < listA.Count; i )
{
orders.Add(listA[i], i);
}
int lastIndex = listA.Count;
foreach (string letter in listB.Select(x=>x.Letter)
.Distinct().Except(listA))
{
orders.Add(letter, lastIndex);
}
uj5u.com熱心網友回復:
這是@nannanas 的 answer方法體的具體實作,它在listA不包含所有字母時也有效listB:
listB = listA.Union(listB.Select(entry => entry.Letter))
.Join(listB,
letter => letter,
sample => sample.Letter,
( _, sample ) => sample)
.ToList();
解釋:
假設我們有以下串列:
var listA = new List<string> { "B", "C", "A" };
var listB = new List<Sample>
{
new Sample { Letter = "E", Number = "1" },
new Sample { Letter = "C", Number = "2" },
new Sample { Letter = "A", Number = "3" },
new Sample { Letter = "B", Number = "4" },
new Sample { Letter = "D", Number = "5" }
};
第一行:
listB.Select(entry => entry.Letter)將提取 中的每個Letter值listB,結果是:
{“E”、“C”、“A”、“B”、“D”}
listA.Union(listB.Select(entry => entry.Letter))通過首先產生 ( ) 集合中的每個不同專案,然后從( )中不存在的s集合中產生每個不同專案,來創建和的值的集合并集;導致:listAlistBLetterlistA"B", "C", "A"LetterlistB listA"E", "D"
{“B”、“C”、“A”、“E”、“D”}
我們現在有了要listB反映的字母順序:首先,由 給出的順序listA,然后是 中存在的剩余字母listB。
TODO:有空的時候再解釋一下。
示例小提琴在這里。
uj5u.com熱心網友回復:
你應該使用這樣的東西
var listA = new List<string> { "B", "C", "A" };
var listB = new List<string> { "A", "B", "C" };
listB = listB.OrderBy(d => listA.IndexOf(d)).ToList();
// listB: "B", "C", "A"
uj5u.com熱心網友回復:
您可以使用這個擴展,它還支持通過特定屬性比較串列中的條目(例如 id 而不是參考)
public static IEnumerable<TFirst> OrderBy<TFirst, TSecond, TKey>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TKey> firstKeySelector, Func<TSecond, TKey> secondKeySelector) =>
second
.Join(
first,
secondKeySelector,
firstKeySelector,
(_, firstItem) => firstItem);
這將以與使用兩個鍵選擇器比較它們second時已經對它們進行排序的方式相同的方式對專案進行排序。first
請注意,這僅在 .in 中的所有鍵first都存在時才有效second。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/431541.html
上一篇:基于屬性對列舉執行LINQ操作
下一篇:如何從嵌套物件串列中洗掉重復項?
