问题
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>();
}
回答1:
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();
回答2:
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()
orArray.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.
回答3:
var sorted = myObj.OrderBy(x => x.marker);
回答4:
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/
回答5:
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!!
}
}
回答6:
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 second 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:
// In-place but unstable sort.
public static void Sort<T>(this IList<T> ilist, /* pass in your comparers here */)
{
switch(ilist)
{
case List<T> list:
list.Sort();
break;
case T[] array:
Array.Sort(array);
break;
default:
var sorted = ilist.ToArray();
sorted.Sort();
for (int i = 0; i < ilist.Count; i++)
{
ilist[i] = sorted[i];
}
break;
}
}
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
来源:https://stackoverflow.com/questions/3844463/how-do-i-sort-ilistclass