0

对不起,但我想我必须在我的问题中加入很多代码。不过好消息是,如果您有时间,您可以将其复制到控制台应用程序中并执行它,这样您就可以看到结果中的问题。

我得到了一个列表(是的,下面代码中的列表实际上就是列表!)。从本质上讲,我将被给予,我只是为了清楚起见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 是分组的。

谁能帮我理解为什么会出现这种行为?

4

1 回答 1

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将每个项目包装在 a 中来做类似的事情。Tuple<int, ListContents>

于 2013-06-12T10:31:35.987 回答