2016-11-30 70 views
0

我想將特定數字移動到此列表的頂部。將列表元素會議條件移動到列表頂部

int numberToBeMovedOnTop = 4; 
List<int> lst = new List<int>(){1, 2, 3, 4, 5, 5, 4, 7, 9, 4, 2, 1}; 
List<int> lstOdd = lst.FindAll(l => l == numberToBeMovedOnTop); 
lstOdd.AddRange(lst.FindAll(l => l != numberToBeMovedOnTop)); 

其中numberToBeMovedOnTop是一個變量。

這給了我想要的結果,但是這是一個更好的解決方案嗎?我可以迭代列表一次,並將第一個元素numberToBeMovedOnTop和第二個元素numberToBeMovedOnTop第二次發生交換,依此類推。但是,這可以用一些內置的C#函數來完成,而不需要兩次迭代列表?

+0

檢查這個問題了,包含了不同的方法負載這樣做http://stackoverflow.com/questions/1668451/use-linq-to-move-item-to-top-of-list –

回答

12

你可以使用LINQ:

List<int> lstOdd = lst.OrderByDescending(i => i == numberToBeMovedOnTop).ToList(); 

爲什麼OrderByDescending?因爲比較返回booltrue高於false。你也可以使用:

List<int> lstOdd = lst.OrderBy(i => i == numberToBeMovedOnTop ? 0 : 1).ToList(); 

注意這是因爲OrderByOrderByDescending正在執行stable sort。這意味着原始訂單仍然適用於所有相同的項目。


對於它的價值,這裏是一個擴展方法,它與任何類型和謂語的作品,是一點點高效:

public static List<T> PrependAll<T>(this List<T> list, Func<T, bool> predicate) 
{ 
    var returnList = new List<T>(); 
    var listNonMatch = new List<T>(); 
    foreach (T item in list) 
    { 
     if (predicate(item)) 
      returnList.Add(item); 
     else 
      listNonMatch.Add(item); 
    } 
    returnList.AddRange(listNonMatch); 
    return returnList; 
} 

用法:List<int> lstOdd = lst.PrependAll(i => i == numberToBeMovedOnTop);

2

除了使用LINQ ,它可能是一樣有效率/可以理解的做到這一點沒有linq

var listToAdd = new List<int>(); 
var listOdd = new List<int>(); 
for(int i = 0; i < lst.Count; i++) 
{ 
    if(lst[i] == numberToBeMovedOnTop) 
    { 
     listToAdd.Add(numberToBeMovedOnTop); 
    } 
    else 
    { 
     listOdd.Add(lst[i]); 
    } 

} 
listOdd.AddRange(listToAdd); 

跟蹤那些你已經刪除的,然後再添加它們

0

集團由謂詞,然後聯合?

 var nums = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
     var grp = nums.GroupBy(x => x % 2 == 0).ToList(); 
     var changed = grp[0].Union(grp[1]).ToList(); 
+0

你的謂詞是不同的,但你明白了 – Jimbobyo