C# 如何使用重复键对列表进行排序?

C# 如何使用重复键对列表进行排序?,c#,data-structures,.net-2.0,generic-list,C#,Data Structures,.net 2.0,Generic List,我从两个不同的配置文件中读取了一组元素/键。因此,键可能是相同的,但与每个键关联的值不同 我想按排序顺序列出它们。我能做什么?我尝试了SortedList类,但它不允许重复键 我怎么做 e、 假设我有3个元素,键为1,2,3。然后我又得到一个元素,它的键为2(但值不同)。然后,我希望在现有密钥2之后但在3之前插入新密钥。如果我再次找到一个具有键2的元素,那么它应该在最近添加的键2之后 请注意,我使用的是.NET 2.0,我更喜欢使用LINQ来实现这类功能: using System.Linq;

我从两个不同的配置文件中读取了一组元素/键。因此,键可能是相同的,但与每个键关联的值不同

我想按排序顺序列出它们。我能做什么?我尝试了
SortedList
类,但它不允许重复键

我怎么做

e、 假设我有3个元素,键为1,2,3。然后我又得到一个元素,它的键为2(但值不同)。然后,我希望在现有密钥2之后但在3之前插入新密钥。如果我再次找到一个具有键2的元素,那么它应该在最近添加的键2之后


请注意,我使用的是.NET 2.0,我更喜欢使用LINQ来实现这类功能:

using System.Linq;

...

var mySortedList = myList.Orderby(l => l.Key)
                         .ThenBy(l => l.Value);

foreach (var sortedItem in mySortedList) {
    //You'd see each item in the order you specified in the loop here.
}

注意:您必须使用.NET 3.5或更高版本才能完成此任务。

.NET不支持稳定排序(这意味着排序时等效元素保持其相对顺序)。但是,您可以使用
List.BinarySearch
和自定义
IComparer
(如果键小于或等于目标,则返回-1,如果键大于目标,则返回+1)编写自己的稳定排序插入


请注意,
List.Sort
不是一个稳定的排序,因此您必须编写自己的稳定快速排序例程,或者只使用插入排序来初始填充集合。

您需要的是一个带有自定义排序的排序函数。现在使用排序时,您拥有的是默认的icomparer。这将检查字段值

创建自定义IComparer时(通过实现接口在类中执行此操作)。它所做的是:您的对象将自己检查到您排序的列表中的每个其他对象

这是由一个函数完成的。(不要担心VS会在引用您的接口时实现它

public class  ThisObjectCLass : IComparable{

    public int CompareTo(object obj) {
            ThisObjectCLass something = obj as ThisObjectCLass ;
            if (something!= null) 
                if(this.key.CompareTo(object.key) == 0){
                //then:
                   if .....
                }
                else if(this.value "is more important then(use some logic here)" something.value){
                 return 1
                }
                else return -1
            else
               throw new ArgumentException("I am a dumb little rabid, trying to compare different base classes");
        }
}
请阅读上面的链接以了解更多信息


我知道我在一开始理解这一点时遇到了一些困难,因此如果需要任何额外的帮助,请添加注释,我将详细说明

如果您不真正关心具有相等键的元素的顺序,请将所有内容添加到列表中,然后按键排序:

static void Main(string[] args)
{
   List<KeyValuePair<int, MyClass>> sortedList = 
      new List<KeyValuePair<int, MyClass>>() {
         new KeyValuePair<int, MyClass>(4, new MyClass("four")), 
         new KeyValuePair<int, MyClass>(7, new MyClass("seven")),
         new KeyValuePair<int, MyClass>(5, new MyClass("five")),
         new KeyValuePair<int, MyClass>(4, new MyClass("four-b")),
         new KeyValuePair<int, MyClass>(7, new MyClass("seven-b"))
      };
   sortedList.Sort(Compare);
}
static int Compare(KeyValuePair<int, MyClass> a, KeyValuePair<int, MyClass> b)
{
   return a.Key.CompareTo(b.Key);
}
static void Main(字符串[]args)
{
列表分类列表=
新名单(){
新的KeyValuePair(4,新的MyClass(“四”)),
新的KeyValuePair(7,新的MyClass(“七”)),
新的KeyValuePair(5,新的MyClass(“5”)),
新的KeyValuePair(4,新的MyClass(“四b”),
新的KeyValuePair(7,新的MyClass(“七b”))
};
排序列表。排序(比较);
}
静态整数比较(KeyValuePair a、KeyValuePair b)
{
返回a.Key.CompareTo(b.Key);
}
如果确实希望稍后插入的项目位于先前插入的项目之后,请在插入时对其进行排序:

class Sorter : IComparer<KeyValuePair<int, MyClass>>
{

static void Main(string[] args)
{
   List<KeyValuePair<int, MyClass>> sortedList = new List<KeyValuePair<int, MyClass>>();
   Sorter sorter = new Sorter();
   foreach (KeyValuePair<int, MyClass> kv in new KeyValuePair<int, MyClass>[] {
      new KeyValuePair<int, MyClass>(4, new MyClass("four")), 
      new KeyValuePair<int, MyClass>(7, new MyClass("seven")),
      new KeyValuePair<int, MyClass>(5, new MyClass("five")),
      new KeyValuePair<int, MyClass>(4, new MyClass("four-b")),
      new KeyValuePair<int, MyClass>(4, new MyClass("four-c")),
      new KeyValuePair<int, MyClass>(7, new MyClass("seven-b")) })
   {
      sorter.Insert(sortedList, kv);
   }
   for (int i = 0; i < sortedList.Count; i++)
   {
      Console.WriteLine(sortedList[i].ToString());
   }
}
void Insert(List<KeyValuePair<int, MyClass>> sortedList, KeyValuePair<int, MyClass> newItem)
{
   int newIndex = sortedList.BinarySearch(newItem, this);
   if (newIndex < 0)
      sortedList.Insert(~newIndex, newItem);
   else
   {
      while (newIndex < sortedList.Count && (sortedList[newIndex].Key == newItem.Key))
         newIndex++;
      sortedList.Insert(newIndex, newItem);
   }
}
#region IComparer<KeyValuePair<int,MyClass>> Members

public int Compare(KeyValuePair<int, MyClass> x, KeyValuePair<int, MyClass> y)
{
   return x.Key.CompareTo(y.Key);
}

#endregion
}
分类机:IComparer
{
静态void Main(字符串[]参数)
{
List sortedList=新列表();
分拣机=新分拣机();
foreach(新KeyValuePair[]中的KeyValuePair kv){
新的KeyValuePair(4,新的MyClass(“四”)),
新的KeyValuePair(7,新的MyClass(“七”)),
新的KeyValuePair(5,新的MyClass(“5”)),
新的KeyValuePair(4,新的MyClass(“四b”),
新的KeyValuePair(4,新的MyClass(“四c”),
新的KeyValuePair(7,新的MyClass(“seven-b”)})
{
分拣机插件(分拣机列表,千伏);
}
对于(int i=0;i
或者,您可以有一个列表的排序列表:

static void Main(string[] args)
{
   SortedDictionary<int, List<MyClass>> sortedList = new SortedDictionary<int,List<MyClass>>();
   foreach (KeyValuePair<int, MyClass> kv in new KeyValuePair<int, MyClass>[] {
      new KeyValuePair<int, MyClass>(4, new MyClass("four")), 
      new KeyValuePair<int, MyClass>(7, new MyClass("seven")),
      new KeyValuePair<int, MyClass>(5, new MyClass("five")),
      new KeyValuePair<int, MyClass>(4, new MyClass("four-b")),
      new KeyValuePair<int, MyClass>(4, new MyClass("four-c")),
      new KeyValuePair<int, MyClass>(7, new MyClass("seven-b")) })
   {
      List<MyClass> bucket;
      if (!sortedList.TryGetValue(kv.Key, out bucket))
         sortedList[kv.Key] = bucket = new List<MyClass>();
      bucket.Add(kv.Value);
   }
   foreach(KeyValuePair<int, List<MyClass>> kv in sortedList)
   {
      for (int i = 0; i < kv.Value.Count; i++ )
         Console.WriteLine(kv.Value[i].ToString());
   }
}
static void Main(字符串[]args)
{
SortedDictionary sortedList=新的SortedDictionary();
foreach(新KeyValuePair[]中的KeyValuePair kv){
新的KeyValuePair(4,新的MyClass(“四”)),
新的KeyValuePair(7,新的MyClass(“七”)),
新的KeyValuePair(5,新的MyClass(“5”)),
新的KeyValuePair(4,新的MyClass(“四b”),
新的KeyValuePair(4,新的MyClass(“四c”),
新的KeyValuePair(7,新的MyClass(“seven-b”)})
{
列表桶;
如果(!sortedList.TryGetValue(千伏键,外桶))
sortedList[kv.Key]=bucket=新列表();
斗加(千伏值);
}
foreach(分类列表中的键值对kv)
{
对于(int i=0;i
我不确定您是否可以像我在上面的第一个示例中那样在.NET 2.0中使用列表初始值设定项,但我确信您知道如何用数据填充列表。

您是否考虑过该类,因为它允许您存储每个键的多个值?例如,您可以具有以下功能:

    NameValueCollection nvc = new NameValueCollection();
    nvc.Add("1", "one");
    nvc.Add("2", "two");
    nvc.Add("3", "three");

    nvc.Add("2", "another value for two");
    nvc.Add("1", "one bis");
然后检索您可能拥有的值:

    for (int i = 0; i < nvc.Count; i++)
    {
        if (nvc.GetValues(i).Length > 1)
        {
            for (int x = 0; x < nvc.GetValues(i).Length; x++)
            {
                Console.WriteLine("'{0}' = '{1}'", nvc.GetKey(i), nvc.GetValues(i).GetValue(x));
            }
        }
        else
        {
            Console.WriteLine("'{0}' = '{1}'", nvc.GetKey(i), nvc.GetValues(i)[0]);
        }

    }
for(int i=0;i1)
{
对于(intx=0;x
其中给出了输出:

“1”=“一”

“1”=“一个二”

“2”=“2”

“2”=“两个的另一个值”


“3'='three'

我是通过创建一个
SortedList
来实现的。每当我找到重复的键时,我只需将该值插入与SortedList对象中已经存在的键相关联的现有列表中。这样,我就可以拥有特定键的值列表。

在.NET 2.0中,您可以编写:

List<KeyValuePair<string, string>> keyValueList = new List<KeyValuePair<string, string>>();

// Simulate your list of key/value pair which key could be duplicate
keyValueList.Add(new KeyValuePair<string,string>("1","One"));
keyValueList.Add(new KeyValuePair<string,string>("2","Two"));
keyValueList.Add(new KeyValuePair<string,string>("3","Three"));

// Here an entry with duplicate key and new value
keyValueList.Add(new KeyValuePair<string, string>("2", "NEW TWO")); 

// Your final sorted list with one unique key
SortedList<string, string> sortedList = new SortedList<string, string>();

foreach (KeyValuePair<string, string> s in keyValueList)
{
    // Use the Indexer instead of Add method
    sortedList[s.Key] = s.Value;
}
这个怎么样

        SortedList<string, List<string>> sl = new SortedList<string, List<string>>();

        List<string> x = new List<string>();

        x.Add("5");
        x.Add("1");
        x.Add("5");
        // use this to load  
        foreach (string z in x)
        {
            if (!sl.TryGetValue(z, out x))
            {
                sl.Add(z, new List<string>());
            }

            sl[z].Add("F"+z);
        }
        // use this to print 
        foreach (string key in sl.Keys)
        {
            Console.Write("key=" + key + Environment.NewLine);

            foreach (string item in sl[key])
            {
                Console.WriteLine(item);
            }
        }
SortedList sl=新的SortedList();
列表x=新列表();
x、 加
        SortedList<string, List<string>> sl = new SortedList<string, List<string>>();

        List<string> x = new List<string>();

        x.Add("5");
        x.Add("1");
        x.Add("5");
        // use this to load  
        foreach (string z in x)
        {
            if (!sl.TryGetValue(z, out x))
            {
                sl.Add(z, new List<string>());
            }

            sl[z].Add("F"+z);
        }
        // use this to print 
        foreach (string key in sl.Keys)
        {
            Console.Write("key=" + key + Environment.NewLine);

            foreach (string item in sl[key])
            {
                Console.WriteLine(item);
            }
        }
public class DegreeComparer : IComparer<int>
{
    #region IComparer<int> Members

    public int Compare(int x, int y)
    {
        if (x < y)
            return -1;
        else
            return 1;
    }

    #endregion
}
var mySortedList = new SortedList<int, string>(new DegreeComparer());
Class ByRankScoreComparer
    Implements IComparer(Of BoardState)

    Public Function Compare(ByVal bs1 As BoardState, ByVal bs2 As BoardState) As Integer Implements IComparer(Of BoardState).Compare
        Dim result As Integer = bs2.RankScore.CompareTo(bs1.RankScore) 'DESCENDING order
        If result = 0 Then
            result = bs1.Index.CompareTo(bs2.Index)
        End If
        Return result
    End Function
End Class
Dim boardStates As SortedSet(Of BoardState)(New ByRankScoreComparer)
Class BoardState
    Private Shared BoardStateIndex As Integer = 0
    Public ReadOnly Index As Integer
    ...
    Public Sub New ()
        BoardStateIndex += 1
        Index = BoardStateIndex
    End Sub
    ...
End Class