2016-11-30 67 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

相关问题