IComparable
昇順または降順で並べ替え、並べ替えているオブジェクト タイプのさまざまなフィールドで並べ替えることができるように、インターフェイスを使用する方法の基本的な例が必要です。
29562 次
6 に答える
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
でonを許可する例を次に示します。List<T>
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)));
}
}
于 2009-01-12T13:47:57.763 に答える
12
簡単な例を次に示します。
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());
}
}
于 2009-01-12T13:34:12.033 に答える
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クラスの「Sort」メソッド:
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 ) );
于 2009-01-12T13:47:39.307 に答える
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);
}
}
于 2015-06-20T18:11:14.470 に答える
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)
}
于 2009-01-12T14:25:48.187 に答える