我需要一個基本的例子來說明如何使用IComparable
接口,以便我可以按升序或降序排序,並按照我正在排序的對象類型的不同字段進行排序。如何使用IComparable界面?
16
A
回答
14
好吧,既然你使用的是List<T>
這將是僅使用Comparison<T>
就簡單多了,例如:
List<Foo> data = ...
// sort by name descending
data.Sort((x,y) => -x.Name.CompareTo(y.Name));
當然,與LINQ你可以只使用:
var ordered = data.OrderByDescending(x=>x.Name);
但List<T>
你可以重新引入這個(就地重新排序)很容易;下面是允許Sort
上List<T>
與lambda語法的例子:
using System;
using System.Collections.Generic;
class Foo { // formatted for vertical space
public string Bar{get;set;}
}
static class Program {
static void Main() {
List<Foo> data = new List<Foo> {
new Foo {Bar = "abc"}, new Foo {Bar = "jkl"},
new Foo {Bar = "def"}, new Foo {Bar = "ghi"}
};
data.SortDescending(x => x.Bar);
foreach (var row in data) {
Console.WriteLine(row.Bar);
}
}
static void Sort<TSource, TValue>(this List<TSource> source,
Func<TSource, TValue> selector) {
var comparer = Comparer<TValue>.Default;
source.Sort((x,y)=>comparer.Compare(selector(x),selector(y)));
}
static void SortDescending<TSource, TValue>(this List<TSource> source,
Func<TSource, TValue> selector) {
var comparer = Comparer<TValue>.Default;
source.Sort((x,y)=>comparer.Compare(selector(y),selector(x)));
}
}
9
這裏有一個簡單的例子:「這是偉大的,但如果我希望能夠通過另一個字段來控制排序順序,或排序什麼」
public class SortableItem : IComparable<SortableItem>
{
public int someNumber;
#region IComparable<SortableItem> Members
public int CompareTo(SortableItem other)
{
int ret = -1;
if (someNumber < other.someNumber)
ret = -1;
else if (someNumber > other.someNumber)
ret = 1;
else if (someNumber == other.someNumber)
ret = 0;
return ret;
}
#endregion
}
簡單。我們所需要做的就是爲對象添加更多的字段。首先,我們將爲不同的排序類型添加一個字符串,然後添加一個布爾值來表示我們是按降序還是按升序排序,然後添加一個字段來確定我們要搜索哪個字段。
public class SortableItem : IComparable<SortableItem>
{
public enum SortFieldType { SortNumber, SortString }
public int someNumber = -1;
public string someString = "";
public bool descending = true;
public SortFieldType sortField = SortableItem.SortFieldType.SortNumber;
#region IComparable<SortableItem> Members
public int CompareTo(SortableItem other)
{
int ret = -1;
if(sortField == SortableItem.SortFieldType.SortString)
{
// A lot of other objects implement IComparable as well.
// Take advantage of this.
ret = someString.CompareTo(other.someString);
}
else
{
if (someNumber < other.someNumber)
ret = -1;
else if (someNumber > other.someNumber)
ret = 1;
else if (someNumber == other.someNumber)
ret = 0;
}
// A quick way to switch sort order:
// -1 becomes 1, 1 becomes -1, 0 stays the same.
if(!descending) ret = ret * -1;
return ret;
}
#endregion
public override string ToString()
{
if(sortField == SortableItem.SortFieldType.SortString)
return someString;
else
return someNumber.ToString();
}
}
「告訴我怎麼做!」
好,因爲你問得很好。
static class Program
{
static void Main()
{
List<SortableItem> items = new List<SortableItem>();
SortableItem temp = new SortableItem();
temp.someString = "Hello";
temp.someNumber = 1;
items.Add(temp);
temp = new SortableItem();
temp.someString = "World";
temp.someNumber = 2;
items.Add(temp);
SortByString(items);
Output(items);
SortAscending(items);
Output(items);
SortByNumber(items);
Output(items);
SortDescending(items);
Output(items);
Console.ReadKey();
}
public static void SortDescending(List<SortableItem> items)
{
foreach (SortableItem item in items)
item.descending = true;
}
public static void SortAscending(List<SortableItem> items)
{
foreach (SortableItem item in items)
item.descending = false;
}
public static void SortByNumber(List<SortableItem> items)
{
foreach (SortableItem item in items)
item.sortField = SortableItem.SortFieldType.SortNumber;
}
public static void SortByString(List<SortableItem> items)
{
foreach (SortableItem item in items)
item.sortField = SortableItem.SortFieldType.SortString;
}
public static void Output(List<SortableItem> items)
{
items.Sort();
for (int i = 0; i < items.Count; i++)
Console.WriteLine("Item " + i + ": " + items[i].ToString());
}
}
4
如果你想動態排序,你可以使用LINQ
var itemsOrderedByNumber = (from item in GetClasses() orderby item.Number select item).ToList();
var itemsOrderedByText = (from item in GetClasses() orderby item.Text select item).ToList();
var itemsOrderedByDate = (from item in GetClasses() orderby item.Date select item).ToList();
或 「分類」 列表類的方法:
List<Class1> itemsOrderedByNumber2 = new List<Class1>(GetClasses());
itemsOrderedByNumber2.Sort((a, b) => Comparer<int>.Default.Compare(a.Number, b.Number));
List<Class1> itemsOrderedByText2 = new List<Class1>(GetClasses());
itemsOrderedByText2.Sort((a, b) => Comparer<string>.Default.Compare(a.Text, b.Text));
List<Class1> itemsOrderedByDate2 = new List<Class1>(GetClasses());
itemsOrderedByDate2.Sort((a, b) => Comparer<DateTime>.Default.Compare(a.Date, b.Date));
0
這可能不是有關排序順序,但它仍然是 - 我認爲 - 一個有趣的使用IComparable
:
public static void MustBeInRange<T>(this T x, T minimum, T maximum, string paramName)
where T : IComparable<T>
{
bool underMinimum = (x.CompareTo(minimum) < 0);
bool overMaximum = (x.CompareTo(maximum) > 0);
if (underMinimum || overMaximum)
{
string message = string.Format(
System.Globalization.CultureInfo.InvariantCulture,
"Value outside of [{0},{1}] not allowed/expected",
minimum, maximum
);
if (string.IsNullOrEmpty(paramName))
{
Exception noInner = null;
throw new ArgumentOutOfRangeException(message, noInner);
}
else
{
throw new ArgumentOutOfRangeException(paramName, x, message);
}
}
}
public static void MustBeInRange<T>(this T x, T minimum, T maximum)
where T : IComparable<T> { x.MustBeInRange(minimum, maximum, null); }
這些簡單的擴展方法允許您執行任何類型的參數範圍檢查,如下所示執行IComparable
:
public void SomeMethod(int percentage, string file) {
percentage.MustBeInRange(0, 100, "percentage");
file.MustBeInRange("file000", "file999", "file");
// do something with percentage and file
// (caller will have gotten ArgumentOutOfRangeExceptions when applicable)
}
0
using System;
using System.Collections.Generic;
using System.Text;
namespace Sorting_ComplexTypes
{
class Program
{
static void Main(string[] args)
{
Customer customer1 = new Customer {
ID = 101,
Name = "Mark",
Salary = 2400,
Type = "Retail Customers"
};
Customer customer2 = new Customer
{
ID = 102,
Name = "Brian",
Salary = 5000,
Type = "Retail Customers"
};
Customer customer3 = new Customer
{
ID = 103,
Name = "Steve",
Salary = 3400,
Type = "Retail Customers"
};
List<Customer> customer = new List<Customer>();
customer.Add(customer1);
customer.Add(customer2);
customer.Add(customer3);
Console.WriteLine("Before Sorting");
foreach(Customer c in customer)
{
Console.WriteLine(c.Name);
}
customer.Sort();
Console.WriteLine("After Sorting");
foreach(Customer c in customer)
{
Console.WriteLine(c.Name);
}
customer.Reverse();
Console.WriteLine("Reverse Sorting");
foreach (Customer c in customer)
{
Console.WriteLine(c.Name);
}
}
}
}
public class Customer : IComparable<Customer>
{
public int ID { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public string Type { get; set; }
public int CompareTo(Customer other)
{
return this.Name.CompareTo(other.Name);
}
}
1
您可以使用此排序列表
namespace GenaricClass
{
class Employee :IComparable<Employee>
{
public string Name { get; set; }
public double Salary { get; set; }
public int CompareTo(Employee other)
{
if (this.Salary < other.Salary) return 1;
else if (this.Salary > other.Salary) return -1;
else return 0;
}
public static void Main()
{
List<Employee> empList = new List<Employee>()
{
new Employee{Name="a",Salary=140000},
new Employee{Name="b",Salary=120000},
new Employee{Name="c",Salary=160000},
new Employee{Name="d",Salary=10000}
};
empList.Sort();
foreach (Employee emp in empList)
{
System.Console.Write(emp.Salary +",");
}
System.Console.ReadKey();
}
}
}
相關問題
- 1. 使用IComparable
- 2. 如何使用IPrintable界面?
- 3. 如何使用界面
- 4. 如何使用phpdoc的web界面?
- 5. 如何使用Xcode設計界面iosopendev?
- 6. 如何使用界面作爲參數?
- 7. 如何正確使用C#界面?
- 8. extjs 3.4如何使用提示界面?
- 9. 如何使用c sharp界面
- 10. 使用了IComparable的AVL樹
- 11. 使用Framework 2.0實現IComparable
- 12. 如何在用戶界面
- 13. .NET IComparable的:如何實現
- 14. FxCop和IComparable/IComparable <T>
- 15. 如何使用其他界面的鍵創建自定義界面?
- 16. IComparable IgnoreCase
- 17. 如何使用Selenium使用鍵盤界面?
- 18. 使用匿名類型和IComparable界面查找文件夾中的最大文件
- 19. Go界面方法使用
- 20. 使用Web界面的SSIS
- 21. 實際使用界面
- 22. 高效使用ICommand界面
- 23. 如何實現界面?
- 24. 如何訪問DropDown界面?
- 25. Java界面如何抽象?
- 26. 如何構造界面?
- 27. 如何獲得此界面?
- 28. 如何重構胖界面?
- 29. 使用IComparable比較對象的問題
- 30. 使用IComparable接口比較int和long
這實際上是相當yeucky,遺憾地說。有更好的方法,特別是使用LINQ或LINQ啓發式的方法...... – 2009-01-12 13:44:15
如果你有更好的主意,沒有任何說你不能回答這個問題。 – 2009-01-12 13:45:37
我有 - 我只是寫它; -p – 2009-01-12 13:49:25