2016-04-28 73 views
4

我有一個List,我想按另一個序列列表排序。C#List <>按另一個List值排列

List<string> Source = new List<string>() { "A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" }; 
List<int> Sequence = new List<int>(){ 2, 1, 3, 5, 4, 6, 7 }; 

我怎樣才能得到新的列表,以便我的結果是一樣

List<string> Output = new List<string>(){ "B" ,"A" ,"C" ,"E" ,"D" ,"F" ,"G" }; 

附:我可以使用下面的代碼來獲得結果。但我想學習另一種方法。

private List<string> ArrangeList(List<string> i_lsData, List<int> i_nSequence) 
    { 
     List<string> lv_lsTempList = new List<string>(); 

     foreach(int Temp in i_nSequence) 
     { 
      lv_lsTempList.Add(i_lsData[Temp]); 
     } 

     return lv_lsTempList; 
    } 
+1

學習使用類而不是多個相關集合。 –

+0

'私人列表 ArrangeList(列表 i_lsData,列表 i_nSequence) { 返回i_nSequence.Zip(i_lsData,(K,V)=>新的{K,V})。的OrderBy(K => KK)。選擇( k => kv).ToList(); }' –

+0

該序列的結果是'{2,3,1,5,4,6,7}'? –

回答

5

您可以使用LINQ基於索引爲你做了排序:

var list = Source.Select((item, index) => new { Item = item, Index = Sequence[index] }) 
       .OrderBy(s => s.Index) 
       .Select(s => s.Item); 

首先,我用Select來獲得該項目的索引SourceSequence找到對應的項。然後,我們對此進行分類並取回原始項目。

0

這裏是一個LINQ版本:

var result = 
    Source 
    .Select((x,i) => new {Item = x, Index = i}) 
    .OrderBy(v => Sequence.IndexOf(v.Index + 1)) 
    .Select(v => v.Item) 
    .ToList(); 
+0

爲什麼使用'IndexOf'命令? –

+0

這就是我試圖解決問題時想到的。有用。但是現在我看到你有一個性能更好的解決方案。如果名單很小,這並不重要。 –

+0

@PatrickHofman,實際上,我們正在解決兩個不同的問題。 –

1

或者使用Zip:

var ordered = Source 
    .Zip(Sequence, (source, seq) => new { Item = source, Index = seq }) 
    .OrderBy(s => s.Index) 
    .Select(s => s.Item); 

郵編兩個成對的可枚舉的項目在相同位置的項目。 lambda表達式可用於創建兩個項目在同一位置的東西(在這種情況下爲匿名方法)。

相對於其他的解決方案,它不叫

Sequence[index] 

在源中的每個項目。而是它將這兩個集合重疊在一起。這對性能更好,並允許在沒有索引訪問時執行相同操作(例如:使用兩個IEnumerables)。