Lambda如何按列表升序重新排序元素并在后面放置空值?

时间:2014-03-03 09:30:00

标签: c# lambda

我说ListA={null,3,2,null}

ListA.OrderBy(x=>x.ID) //would return me null,null,2,3

如果我的目标是获得2,3,null,null,那么我目前只能想出提取空项目,并手动泵入后面。

是否有一个干净的方法会让我回复2,3,null,null

3 个答案:

答案 0 :(得分:8)

您可以使用OrderByDescending + ThenBy(假设它是List<int?>):

var orderedList = ListA
     .OrderByDescending(x => x.HasValue)
     .ThenBy(x => x);

x.HasValue返回truefalse,其中true高于false。这就是我使用OrderByDescending的原因。

如果您想对原始列表进行排序,我会将List.Sort与自定义Compaison<T>一起使用,将null视为最高值:

ListA.Sort((a1, a2) => (a1 ?? int.MaxValue).CompareTo(a2 ?? int.MaxValue));

这更有效,因为它不需要创建新列表。

答案 1 :(得分:2)

作为Tim回答的替代方案,您可以编写自己的IComparer<T>,为您执行自定义排序算法。

var array = list.OrderBy(x => x, new NullableIntComparer())
            .ToArray();

class NullableIntComparer : IComparer<int?>
{
    public int Compare(int? x, int? y)
    {
        if (x.HasValue && y.HasValue)
        {
            return x.Value.CompareTo(y.Value);
        }
        if (x.HasValue)
        {
            return -1;
        }
        if (y.HasValue)
        {
            return 1;
        }
        return 0;
    }
}

答案 2 :(得分:0)

尝试以下方法:

class Program
    {
        class A
        {
            public A(){}
            public int? ID { get; set; }
        }
        static void Main(string[] args)
        {
            var listA = new List<A>
                {
                    new A(){ID = null},
                    new A(){ID = 2},
                    new A(){ID = null},
                    new A(){ID = 3},

                };

            var result = listA.OrderByDescending(x => x.ID != null).ThenBy(x => x.ID);

            foreach (var a in result)
            {
                Console.WriteLine(a.ID);
            }

        }
    }