如何对 IList进行排序?

发布于 2024-09-26 10:53:59 字数 377 浏览 2 评论 0原文

IList 没有 Sort() 函数。有人可以帮我解决这个问题吗? 我想对我自己的 IList 进行排序。

假设这是我的 IList:

public class MyObject() 
{
 public int number { get; set; }
 public string marker { get; set; }
}

如何使用标记字符串对 myobj 进行排序?

public void SortObject()
{
 IList<MyObject> myobj = new List<MyObject>();
}

There's no Sort() function for IList. Can someoene help me with this?
I want to sort my own IList.

Suppose this is my IList:

public class MyObject() 
{
 public int number { get; set; }
 public string marker { get; set; }
}

How do I sort myobj using the marker string?

public void SortObject()
{
 IList<MyObject> myobj = new List<MyObject>();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

沙与沫 2024-10-03 10:54:00

使用 OrderBy

示例

public class MyObject() 
{
    public int number { get; set; }
    public string marker { get; set; }
}

IList<MyObject> myobj = new List<MyObject>();
var orderedList = myobj.OrderBy(x => x.marker).ToList();

作为案例不敏感你应该使用 IComparer

public class CaseInsensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
    }
}

IList<MyObject> myobj = new List<MyObject>();
var orderedList = myobj.OrderBy(x => x.marker, new CaseInsensitiveComparer()).ToList();

Use OrderBy

Example

public class MyObject() 
{
    public int number { get; set; }
    public string marker { get; set; }
}

IList<MyObject> myobj = new List<MyObject>();
var orderedList = myobj.OrderBy(x => x.marker).ToList();

For a case insensitive you should use a IComparer

public class CaseInsensitiveComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        return string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
    }
}

IList<MyObject> myobj = new List<MyObject>();
var orderedList = myobj.OrderBy(x => x.marker, new CaseInsensitiveComparer()).ToList();
逆蝶 2024-10-03 10:54:00

我会反对使用 OrderBy 与列表,因为它是一个 LINQ 扩展方法,因此:

  • 它将列表包装在一个可枚举中,然后枚举它并填充一个新的临时列表,然后对这个新列表进行排序。
  • 它将排序列表包装在另一个可枚举中。
  • 然后,当您调用 ToList() 时,它会对其进行迭代并用项目填充另一个新列表。

本质上:除了实际排序之外,它还创建并填充 2 个新列表和 2 个可枚举值。
相比之下,List.Sort() 就地排序并且不创建任何内容,因此效率更高。

我的建议是:

  • 如果您知道基础类型,请使用 List.Sort()Array.Sort(array)
  • 如果您不知道基础类型,请复制将 List 保存到临时数组并使用 Array.Sort(array) 对其进行排序并返回。

I would go against using OrderBy with a list because it's a LINQ extension method, therefore:

  • It wraps the list in an enumerable, then enumerates it and fills a new temporary list, then sorts this new list.
  • It wraps the sorted list inside another enumerable.
  • Then when you call ToList(), it iterates on it and fills another new list with the items.

In essence: it creates and fills 2 new lists and 2 enumerables in addition to the actual sorting.
In comparison, List.Sort() sorts in place and create nothing so it's way more efficient.

My recommendation would be:

  • If you know the underlying type, use List.Sort() or Array.Sort(array)
  • If you don't know the underlying type, copy the List to a temporary array and sort it using Array.Sort(array) and return it.
丶视觉 2024-10-03 10:54:00
var sorted = myObj.OrderBy(x => x.marker);
var sorted = myObj.OrderBy(x => x.marker);
微凉 2024-10-03 10:54:00

OrderBy 肯定可以完成工作,但我个人更喜欢 List.Sort 的语法,因为您可以为其提供一个 Comparison 委托必须编写一个实现 IComparer 的类。我们可以使用扩展方法来实现该目标,如果您对此感兴趣,请查看 SortExtensions:

http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/

OrderBy definitely gets the job done, but I personally prefer the syntax of List.Sort because you can feed it a Comparison<T> delegate instead of having to write a class that implements IComparer<T>. We can accomplish that goal with an extension method, and if that's something you're interested in, check out SortExtensions:

http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/

热风软妹 2024-10-03 10:54:00

要了解为什么不使用 OrderBy 或类似的信息,请查看 Christophe 的回答

这是进行快速排序的一种尝试:

public static void Sort<T>(this IList<T> ilist)
{
    switch(ilist)
    {
        case List<T> lst:
            lst.Sort();
            break;
        case Array arr:
            Array.Sort(arr);
            break;
        default:
            throw new NotImplementedException();
            // or add slow impl if you don't want this to fail!!
    }
}

For explanation why not to use OrderBy or similar check Christophe's answer.

Here is one attempt to make fast Sort:

public static void Sort<T>(this IList<T> ilist)
{
    switch(ilist)
    {
        case List<T> lst:
            lst.Sort();
            break;
        case Array arr:
            Array.Sort(arr);
            break;
        default:
            throw new NotImplementedException();
            // or add slow impl if you don't want this to fail!!
    }
}
盗琴音 2024-10-03 10:54:00

要就地排序,您基本上会看到这两种方法:

        IList<T> list = .... // your ilist
        var sorted = list.ToArray();
        Array.Sort(sorted);

        for (int i = 0; i < list.Count; i++)
        {
            list[i] = sorted[i];
        }

第二种方法

        IList<T> list = .... // your ilist
        ArrayList.Adapter((IList)list).Sort();

可能看起来更简单但对于值类型集合来说不太好,因为它会导致装箱惩罚。此外,无法保证您的 IList 将实现 IList。在我看来,第一个更好。


您还可以使用第一种方法就地对 ICollection 进行排序,但由于 ICollection合约不保证订单(想想哈希结构)。无论如何,向您展示代码示例:

    ICollection<T> collection = .... // your icollection
    var sorted = collection.ToArray();
    Array.Sort(sorted);

    collection.Clear();
    foreach (var i in sorted)
    {
       collection.Add(i);
    }

关于排序稳定性的说明,.NET 的数组/列表排序算法不稳定。 对于稳定的排序,您必须使用

        IList<T> list = .... // your ilist
        var sorted = list.OrderBy(i => i).ToArray();

        for (int i = 0; i < list.Count; i++)
        {
            list[i] = sorted[i];
        }

这不可能像不稳定的排序那么快。


最后,为了完整的答案,也许watbywbarif 采用的复合方法更好:

    public static void Sort<T>(this IList<T> list, IComparer<T> comparer, bool stable)
    {
        if (stable)
        {
            list.StableSort(comparer);
        }
        else
        {
            list.UnstableSort(comparer);
        }
    }

    static void StableSort<T>(this IList<T> list, IComparer<T> comparer)
    {
        list.OrderBy(x => x, comparer).CopyTo(list);
    }

    static void UnstableSort<T>(this IList<T> list, IComparer<T> comparer)
    {
        switch (list)
        {
            case List<T> l:
                l.Sort(comparer);
                break;

            case T[] a:
                Array.Sort(a, comparer);
                break;

            default:
                T[] sortable = list.ToArray();
                sortable.UnstableSort(comparer);
                sortable.CopyTo(list);
                break;
        }
    }

    static void CopyTo<T>(this IEnumerable<T> source, IList<T> target)
    {
        int i = 0;
        foreach (T item in source)
        {
            target[i++] = item;
        }
    }

这就是内置方法。为了更快地实施,您必须推出自己的,请参阅:https://stackoverflow.com/a/19167475

To sort in-place you would essentially see these two approaches:

        IList<T> list = .... // your ilist
        var sorted = list.ToArray();
        Array.Sort(sorted);

        for (int i = 0; i < list.Count; i++)
        {
            list[i] = sorted[i];
        }

and

        IList<T> list = .... // your ilist
        ArrayList.Adapter((IList)list).Sort();

The second one might look simpler but won't be great for value type collections since it incur boxing penalties. Furthermore there is no guarantee your IList<T> will be implementing IList. First one is better IMO.


You can also use the first approach to sort an ICollection<T> in-place but it is questionable if you should expose such a functionality since ICollection<T> contract doesn't guarantee an order (think hash structures). Anyway to show you code example:

    ICollection<T> collection = .... // your icollection
    var sorted = collection.ToArray();
    Array.Sort(sorted);

    collection.Clear();
    foreach (var i in sorted)
    {
       collection.Add(i);
    }

A note on sort stability, .NET's Array/List sorting algorithms are unstable. For a stable sort you will have to use:

        IList<T> list = .... // your ilist
        var sorted = list.OrderBy(i => i).ToArray();

        for (int i = 0; i < list.Count; i++)
        {
            list[i] = sorted[i];
        }

This can't be as fast as unstable sorts.


Finally, for a complete answer, perhaps a composite approach taken by watbywbarif is better:

    public static void Sort<T>(this IList<T> list, IComparer<T> comparer, bool stable)
    {
        if (stable)
        {
            list.StableSort(comparer);
        }
        else
        {
            list.UnstableSort(comparer);
        }
    }

    static void StableSort<T>(this IList<T> list, IComparer<T> comparer)
    {
        list.OrderBy(x => x, comparer).CopyTo(list);
    }

    static void UnstableSort<T>(this IList<T> list, IComparer<T> comparer)
    {
        switch (list)
        {
            case List<T> l:
                l.Sort(comparer);
                break;

            case T[] a:
                Array.Sort(a, comparer);
                break;

            default:
                T[] sortable = list.ToArray();
                sortable.UnstableSort(comparer);
                sortable.CopyTo(list);
                break;
        }
    }

    static void CopyTo<T>(this IEnumerable<T> source, IList<T> target)
    {
        int i = 0;
        foreach (T item in source)
        {
            target[i++] = item;
        }
    }

That's as far as built-in approaches go. For faster implemenation you will have to roll out your own, see: https://stackoverflow.com/a/19167475

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文