任何人都可以提供帮助,我在排序方面遇到问题,我认为我对它进行了排序,但似乎无法正常工作。
我有一个存储以下值的列表
8,6,10,11,7
我还有另一个List(我班上的附件,它有一个名为accessoryId的属性,当前类的顺序是id,当前是6,7,8,10,11)
因此我需要将它们从6,7,8,10,11排序到从简单列表中使用的顺序,即8,6,10,11,7
我有我的icomparable(见下文),我这样打电话 - 它确实输入但是出了点问题,因为列表仍然有我所有的课程,但仍然是6,7,8,10,11的顺序< / p>
// accesories is the IList<Accessories> (hence why i am use ToList)
// and sortOrder is the simple int list list<int>
accesories.ToList().Sort(new ItemTpComparer(sortOrder));
class ItemTpComparer : IComparer<Accessories>
{
private IList<int> otherList;
public ItemTpComparer(IList<int> otherList)
{
this.otherList = otherList;
}
#region IComparer<Accessories> Members
public int Compare(Accessories x, Accessories y)
{
if (otherList.IndexOf(x.AccessoryId) > otherList.IndexOf(y.AccessoryId))
return 1;
else if (otherList.IndexOf(x.AccessoryId) < otherList.IndexOf(y.AccessoryId))
return -1;
else
return 0;
// tried below also didn't work
//return otherList.IndexOf(x.AccessoryId) - otherList.IndexOf(y.AccessoryId);
答案 0 :(得分:9)
比较器是正确的(即使是注释的单行版本)。问题是ToList()
创建了一个新的List
,其中包含IEnumerable<T>
对象中的元素副本,所以基本上,您正在创建一个新列表,对其进行排序并将其丢弃。
var sortedList = accesories.ToList();
sortedList.Sort(new ItemTpComparer(sortOrder));
我建议替换为:
var sortedList = accessories.OrderBy(sortOrder.IndexOf).ToList();
通过这种方式,不需要比较器实现。您也可以轻松按降序排序:
var sortedList = accessories.OrderByDescending(sortOrder.IndexOf).ToList();
如果对象确实是List<Accessories>
,您还可以对其进行排序:
((List<Accessories>)accessories).Sort(new ItemTpComparer(sortOrder));
答案 1 :(得分:1)
Mehrdad向您展示了为什么列表没有排序。我想解决比较器的性能问题,以及排序项比排序项更少的问题。
在列表上使用IndexOf来定位索引是非常低效的。我必须遍历列表中的项目以找到正确的项目。使用字典作为查找,这样您只需循环遍历项目一次:
class ItemTpComparer : IComparer<Accessories> {
private Dictionary<int, int> index;
public ItemTpComparer(IList<int> otherList) {
index = new Dictionary<int, int>();
for (int i = 0; i < otherList.Count; i++) {
index.Add(otherList[i], i);
}
}
public int Compare(Accessories x, Accessories y) {
return index[x.AccessoryId].CompareTo(index[y.AccessoryId]);
}
}
如果要允许排序的值列表短于要排序的项目列表,请检查字典中是否存在该值:
public int Compare(Accessories x, Accessories y) {
int xIndex, yIndex;
if (!index.TryGetValue(x.AccessoryId, out xIndex)) xIndex = int.MaxValue;
if (!index.TryGetValue(y.AccessoryId, out yIndex)) yIndex = int.MaxValue;
return xIndex.CompareTo(yIndex);
}