对不起,我想我必须在我的问题中加入很多代码。好消息是,如果你有时间,你可以将其复制到控制台应用程序中并执行它,这样你就可以看到结果的问题。
我已经获得了一个列表(是的,下面代码中的列表实际上是列表!)。从本质上讲,我将获得List<string, string>
,我将称之为List<ColLeft, ColRight>
,只是为了清晰起见。
ColLeft已经分组,必须保持分组。
ColRight不是按字母顺序排列的,需要在其组内。
我使用的是.NET 2.0,因此我实现了IComparable<T>
。但是,列表无序返回,我无法理解为什么(在VS2005或VS2010上运行同样的问题)。
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace SortingLists
{
class Program
{
static void Main()
{
List<ListContents> listContents = ListContents.GetListContents();
WriteOut(listContents);
Console.WriteLine("\r\n");
listContents.Sort();
WriteOut(listContents);
Console.ReadKey();
}
private static void WriteOut(List<ListContents> listContents)
{
foreach (ListContents content in listContents)
Console.WriteLine(content.ColLeft + " --- " + content.ColRight);
}
}
struct ListContents : IComparable<ListContents>
{
#region Constructor
public ListContents(string l, string r)
{
this.ColLeft = l;
this.ColRight = r;
}
#endregion
#region Fields
public string ColLeft;
public string ColRight;
#endregion
#region IComparable<ListContents> Members
public int CompareTo(ListContents other)
{
if (this.ColLeft.CompareTo(other.ColLeft) == -1)
return this.ColLeft.CompareTo(other.ColLeft);
else
return this.ColRight.CompareTo(other.ColRight);
}
#endregion
#region Methods
public static List<ListContents> GetListContents()
{
List<ListContents> lcList = new List<ListContents>();
lcList.Add(new ListContents("UFT", "a"));
lcList.Add(new ListContents("UFT", "c"));
lcList.Add(new ListContents("UFT", "b"));
lcList.Add(new ListContents("RT", "f"));
lcList.Add(new ListContents("RT", "e"));
lcList.Add(new ListContents("RT", "d"));
lcList.Add(new ListContents("UT", "m"));
lcList.Add(new ListContents("UT", "o"));
lcList.Add(new ListContents("UT", "n"));
return lcList;
}
}
我可以解决它 - 如果我将GetListContents()的顺序改为像......
public static List<ListContents> GetListContents()
{
List<ListContents> lcList = new List<ListContents>();
lcList.Add(new ListContents("UFT", "a"));
lcList.Add(new ListContents("UFT", "c"));
lcList.Add(new ListContents("UFT", "b"));
lcList.Add(new ListContents("RT", "e"));
lcList.Add(new ListContents("RT", "f"));//Moved this item
lcList.Add(new ListContents("RT", "d"));
lcList.Add(new ListContents("UT", "m"));
lcList.Add(new ListContents("UT", "o"));
lcList.Add(new ListContents("UT", "n"));
return lcList;
}
...然后结果按照需要出来。显然这不是一个修复,因为我无法预测List将进入的顺序,唯一的常数是ColLeft被分组。
任何人都可以帮助我理解这种行为的原因吗?
答案 0 :(得分:1)
由于您未在任何地方保留原始订单,因此无法按顺序退回列表。在LINQ(.NET 3.x)中,您可以按如下方式执行此操作:
list.GroupBy(x => x.LeftCol)
.Select(g => g.OrderBy(x => x.RightCol))
.SelectMany(x => x)
.ToList();
在.NET 2.0中,你必须做类似的事情;即,由LeftCol组成的第一组,然后用RightCol对每个组进行排序,然后连接这些组。
例如,如果您控制ListContents
类,则可以添加表示要保留的顺序的字段或属性int Index
(第一组为0;第二组为1;等等)。然后使用比较器对其进行排序,首先按Index
进行比较,然后按RightCol
进行比较:
int index = 0;
for(int i=0; i<list.Count; i++)
{
if (i > 0 && list[i].LeftCol != list[i - 1].LeftCol) index++;
list[i].Index = index;
}
...
public int CompareTo(ListContents other)
{
int result = this.Index.CompareTo(other.Index);
if (result != 0) return result;
return this.ColRight.CompareTo(other.ColRight);
}
如果您不想修改ListContents
类,可以通过在排序前将每个项目包装在Tuple<int, ListContents>
中来执行类似的操作。