当我得到 CompareTo() 时,如何按顺序在排序的 C# List 中插入多个对象
How to insert multiple objects in sorted C# List by order, when I got CompareTo()
我的作业任务:我在 C# 中得到了通用列表,我在实现 CompareTo()
时用 List.Sort
对它进行了排序。我有另一个相同结构对象的列表,我需要将它们插入到我的第一个排序列表中,而不是将它们添加到列表的末尾,然后再次 List.Sort
,而是立即插入到已排序的列表中,并在插入后对列表进行排序。我该怎么做?
长话短说:我不能使用 SortedList,只能使用通用列表,我不能将我的项目添加到 MyList1 的末尾,然后 MyList1.Sort()
我的列表如下所示:
List<MyClass> MyList1 = new List<MyClass>():
List<MyClass> MyList2 = new List<MyClass>()
MyList1.Sort();
我需要 MyList2
中的项目按照排序的相同顺序插入到 MyList1
中。
我的 CompareTo()
方法,它按两个属性排序:
public int CompareTo(MyClass next)
{
int pos = String.Compare(this.name, next.name, StringComparison.CurrentCulture);
if ((this.price < next.price) || ((this.price== next.price)
&& (pos > 0)))
{
return 1;
}
else
{
return - 1;
}
}
我想出了它应该是什么样子,效果很好:
static void Inserting(List<MyClass> List1,
List<MyClass> List2)
{
foreach (var item in List2)
{
var i = 0;
while (i < List1.Count && item.CompareTo(List1[i]) > 0)
i++;
List1.Insert(i, item);
}
}
如果你想把它插入到正确的位置,你有以下三种选择:
- 找到正确的位置,然后
Insert
就在那里
- 使用预先排序的列表,例如
SortedList<TKey,TValue>
或 SortedSet<T>
(取决于您的需要),然后 add(注意:SortedList<TKey,TValue>
要求唯一键;SortedSet<T>
应用唯一值)
- 只需
AddRange()
第二个列表并再次调用 Sort()
“1”的问题是 高效地 为每个新元素找到正确的位置是很尴尬的。如果这是一个数组,您可以使用 Array.BinarySearch
- 如果未找到匹配项,它 return 是适当索引的按位补码。您可以 实现 手动对 List<T>
进行二分搜索,但是.. 这并不好玩。 对于 1,您希望使用 BinarySearch
存在于列表中(感谢@mjwills),请注意 return 未找到匹配项时的值是一个按位补码,告诉您将其插入何处。但是您仍然需要为每个元素执行此操作,这会加起来。
就我个人而言,我会被 SortedSet<T>
诱惑,或者只是在 List<T>
上调用 AddRange()
+ Sort()
您可以覆盖 List Add 方法并像下面的示例那样做
public class MyClass : IComparable<MyClass>
{
public string Name
{
get;
set;
}
public int Desc
{
get;
set;
}
public int CompareTo(MyClass other)
{
return Name.CompareTo(other.Name);
}
}
public class MyList<T> : List<T> where T : IComparable<T>
{
public new void Add(T item)
{
if (base.Count == 0)
{
base.Add(item);
return;
}
if (base[base.Count - 1].CompareTo(item) <= 0)
{
base.Add(item);
return;
}
if (base[0].CompareTo(item) >= 0)
{
base.Insert(0, item);
return;
}
int index = base.BinarySearch(item);
if (index < 0)
index = ~index;
base.Insert(index, item);
base.Add(item);
}
}
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Name = "B";
MyClass myClass1 = new MyClass();
myClass1.Name = "A";
MyClass myClass2 = new MyClass();
myClass2.Name = "C";
MyClass myClass3 = new MyClass();
myClass3.Name = "A";
MyList<MyClass>mylist= new MyList<MyClass>();
mylist.Add(myClass);
mylist.Add(myClass1);
mylist.Add(myClass2);
mylist.Add(myClass3);
Console.ReadKey();
}
我的列表将始终在此处排序。
我的作业任务:我在 C# 中得到了通用列表,我在实现 CompareTo()
时用 List.Sort
对它进行了排序。我有另一个相同结构对象的列表,我需要将它们插入到我的第一个排序列表中,而不是将它们添加到列表的末尾,然后再次 List.Sort
,而是立即插入到已排序的列表中,并在插入后对列表进行排序。我该怎么做?
长话短说:我不能使用 SortedList,只能使用通用列表,我不能将我的项目添加到 MyList1 的末尾,然后 MyList1.Sort()
我的列表如下所示:
List<MyClass> MyList1 = new List<MyClass>():
List<MyClass> MyList2 = new List<MyClass>()
MyList1.Sort();
我需要 MyList2
中的项目按照排序的相同顺序插入到 MyList1
中。
我的 CompareTo()
方法,它按两个属性排序:
public int CompareTo(MyClass next)
{
int pos = String.Compare(this.name, next.name, StringComparison.CurrentCulture);
if ((this.price < next.price) || ((this.price== next.price)
&& (pos > 0)))
{
return 1;
}
else
{
return - 1;
}
}
我想出了它应该是什么样子,效果很好:
static void Inserting(List<MyClass> List1,
List<MyClass> List2)
{
foreach (var item in List2)
{
var i = 0;
while (i < List1.Count && item.CompareTo(List1[i]) > 0)
i++;
List1.Insert(i, item);
}
}
如果你想把它插入到正确的位置,你有以下三种选择:
- 找到正确的位置,然后
Insert
就在那里 - 使用预先排序的列表,例如
SortedList<TKey,TValue>
或SortedSet<T>
(取决于您的需要),然后 add(注意:SortedList<TKey,TValue>
要求唯一键;SortedSet<T>
应用唯一值) - 只需
AddRange()
第二个列表并再次调用Sort()
“1”的问题是 高效地 为每个新元素找到正确的位置是很尴尬的。如果这是一个数组,您可以使用 对于 1,您希望使用 Array.BinarySearch
- 如果未找到匹配项,它 return 是适当索引的按位补码。您可以 实现 手动对 List<T>
进行二分搜索,但是.. 这并不好玩。BinarySearch
存在于列表中(感谢@mjwills),请注意 return 未找到匹配项时的值是一个按位补码,告诉您将其插入何处。但是您仍然需要为每个元素执行此操作,这会加起来。
就我个人而言,我会被 SortedSet<T>
诱惑,或者只是在 List<T>
AddRange()
+ Sort()
您可以覆盖 List Add 方法并像下面的示例那样做
public class MyClass : IComparable<MyClass>
{
public string Name
{
get;
set;
}
public int Desc
{
get;
set;
}
public int CompareTo(MyClass other)
{
return Name.CompareTo(other.Name);
}
}
public class MyList<T> : List<T> where T : IComparable<T>
{
public new void Add(T item)
{
if (base.Count == 0)
{
base.Add(item);
return;
}
if (base[base.Count - 1].CompareTo(item) <= 0)
{
base.Add(item);
return;
}
if (base[0].CompareTo(item) >= 0)
{
base.Insert(0, item);
return;
}
int index = base.BinarySearch(item);
if (index < 0)
index = ~index;
base.Insert(index, item);
base.Add(item);
}
}
static void Main(string[] args)
{
MyClass myClass = new MyClass();
myClass.Name = "B";
MyClass myClass1 = new MyClass();
myClass1.Name = "A";
MyClass myClass2 = new MyClass();
myClass2.Name = "C";
MyClass myClass3 = new MyClass();
myClass3.Name = "A";
MyList<MyClass>mylist= new MyList<MyClass>();
mylist.Add(myClass);
mylist.Add(myClass1);
mylist.Add(myClass2);
mylist.Add(myClass3);
Console.ReadKey();
}
我的列表将始终在此处排序。