将满足条件的列表元素移动到列表顶部

Sah*_*rma 0 c#

我想将特定号码移到此列表的顶部.

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));
Run Code Online (Sandbox Code Playgroud)

numberToBeMovedOnTop变量在哪里?

这给了我想要的结果,但对此更好的解决方案?我可以迭代列表一次并交换第numberToBeMovedOnTop一个元素的第一个出现,第二numberToBeMovedOnTop个元素的第二个出现,依此类推.但是这可以通过一些内置的C#函数来完成,而无需迭代列表两次吗?

Tim*_*ter 12

您可以使用LINQ:

List<int> lstOdd = lst.OrderByDescending(i => i == numberToBeMovedOnTop).ToList();
Run Code Online (Sandbox Code Playgroud)

为什么OrderByDescending?因为比较返回a bool并且true高于false.你也可以使用:

List<int> lstOdd = lst.OrderBy(i => i == numberToBeMovedOnTop ? 0 : 1).ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,这是因为OrderBy并且OrderByDescending正在执行稳定的排序.这意味着原始订单仍然适用于所有相同的项目.


对于它的价值,这里有一个扩展方法,适用于任何类型和谓词,并且更有效:

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;
}
Run Code Online (Sandbox Code Playgroud)

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