如何对 IEnumable < string > 进行排序

我如何按字母顺序排序 IEnumerable<string>。这可能吗?

编辑: 如何编写就地解决方案?

103517 次浏览

就像你对其他可列举的东西进行排序一样:

var result = myEnumerable.OrderBy(s => s);

或者

var result = from s in myEnumerable
orderby s
select s;

或(忽略个案)

var result = myEnumerable.OrderBy(s => s,
StringComparer.CurrentCultureIgnoreCase);

Note that, as is usual with LINQ, this creates a new IEnumerable<T> which, when enumerated, returns the elements of the original IEnumerable<T> in sorted order. It does not sort the IEnumerable<T> in-place.


IEnumable < T > 是只读的,也就是说,您只能从中检索元素,但不能直接修改它。如果希望就地对字符串集合进行排序,则需要对实现 IEnumable < string > 的原始集合进行排序,或者首先将 IEnumable < string > 转换为可排序集合:

List<string> myList = myEnumerable.ToList();
myList.Sort();

根据你的评论:

_components = (from c in xml.Descendants("component")
let value = (string)c
orderby value
select value
)
.Distinct()
.ToList();

或者

_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.OrderBy(v => v)
.ToList();

或者(如果您想稍后向列表中添加更多项并保持其排序)

_components = xml.Descendants("component")
.Select(c => (string)c)
.Distinct()
.ToList();


_components.Add("foo");
_components.Sort();

这是不可能的,但并非如此。

基本上,任何排序方法都会将 IEnumerable复制到 List中,对 List进行排序,然后返回排序后的列表,即 IEnumerableIList

这意味着您失去了 IEnumerable的“持续无限”属性,但是您无论如何也不能对其进行排序。

myEnumerable = myEnumerable.OrderBy(s => s);

我们不能总是在合适的地方做,但我们会在可能的时候检测:

IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, IComparer<T> cmp)
{
List<T> listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
listToSort.Sort(cmp);
return listToSort;
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, Comparison<T> cmp)
{
return SortInPlaceIfCan(src, new FuncComparer<T>(cmp));
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src)
{
return SortInPlaceIfCan(src, Comparer<T>.Default);
}

这使用了以下方便的结构:

internal struct FuncComparer<T> : IComparer<T>
{
private readonly Comparison<T> _cmp;
public FuncComparer(Comparison<T> cmp)
{
_cmp = cmp;
}
public int Compare(T x, T y)
{
return _cmp(x, y);
}
}