当前位置:
首页 > 编程开发 > Objective-C编程 >
-
c#泛型秘诀5.1
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
4.8 反转Sorted List里的内容
问题
您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedList和SortedList<T>类原来的功能。无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表。
解决方案
ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。
在实例化ReversibleSortedList<TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:
ReversibleSortedList<int, string> rsl = new ReversibleSortedList<int, string>();
rsl.Add(2, "2");
rsl.Add(5, "5");
rsl.Add(3, "3");
rsl.Add(1, "1");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
列表输出显示为按升序排序(默认):
1 1 2 2 3 3 5 5现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Descending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
Compare方法使用了SortDirectionComparer<T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList<TKey, TValue>的内部类SortDirectionComparer<T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList<TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:
public void Sort()
{
//检查是否跟现有排序方向相同.
if (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
讨论
例4-3是ReversibleSortedList<TKey, TValue>类的所有代码:
(译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)
例4-3 ReversibleSortedList类
[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
public class ReversibleSortedList<TKey, TValue> :
IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>,
IDictionary, ICollection, IEnumerable
{
SortDirectionComparer类定义#region SortDirectionComparer类定义
public class SortDirectionComparer<T> : IComparer<T>
{ //ListSortDirection 枚举,有两个值:
//Ascending按升序排列,Descending按降序排列
private System.ComponentModel.ListSortDirection _sortDir;
//构造方法
public SortDirectionComparer()
{ //默认为升序
_sortDir = ListSortDirection.Ascending;
}
//重载构造方法
public SortDirectionComparer(ListSortDirection sortDir)
{
_sortDir = sortDir;
}
//排序方向属性
public System.ComponentModel.ListSortDirection SortDirection
{
get { return _sortDir; }
set { _sortDir = value; }
}
//实现IComparer<T>接口的方法
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// If order is DESC, reverse this comparison.
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
#endregion // SortDirectionComparer
构造方法#region 构造方法
//类型构造器
static ReversibleSortedList()
{
ReversibleSortedList<TKey, TValue>.emptyKeys = new TKey[0];
ReversibleSortedList<TKey, TValue>.emptyValues = new TValue[0];
}
//无参构造方法
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
//用于指定排序方向的构造方法
public ReversibleSortedList(SortDirectionComparer<TKey> comparer)
: this()
{
if (comparer != null)
{
this._sortDirectionComparer = comparer;
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
}
//用于指定字典的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary)
: this(dictionary, (SortDirectionComparer<TKey>)null)
{
}
//用于指定列表容量的构造方法
public ReversibleSortedList(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException(
"capacity", "Non-negative number required");
}
this.keys = new TKey[capacity];
this.values = new TValue[capacity];
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
//用于指定字典和排序方向的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary,
SortDirectionComparer<TKey> comparer)
: this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values,
this._sortDirectionComparer);
this._size = dictionary.Count;
}
//用于指定容量和排序方向的构造方法
public ReversibleSortedList(int capacity, SortDirectionComparer<TKey> comparer)
: this(comparer)
{
this.Capacity = capacity;
}
#endregion //CTORS
公有方法#region 公有方法
//添加元素
public void Add(TKey key, TValue value)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 >= 0)
{
throw new ArgumentException("Attempting to add duplicate");
}
this.Insert(~num1, key, value);
}
//ICollection<KeyValuePair<TKey, TValue>>接口方法实现
public void Clear()
{
this.version++;
Array.Clear(this.keys, 0, this._size);
Array.Clear(this.values, 0, this._size);
this._size = 0;
}
//判断是否包含指定键
public bool ContainsKey(TKey key)
{
return (this.IndexOfKey(key) >= 0);
}
//判断是否包含指定值
public bool ContainsValue(TValue value)
{
return (this.IndexOfValue(value) >= 0);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new ReversibleSortedList<TKey, TValue>.Enumerator<TKey, TValue>(
this);
}
//查找指定键
public int IndexOfKey(TKey key)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 < 0)
{
return -1;
}
return num1;
}
//查找指定值
public int IndexOfValue(TValue value)
{
return Array.IndexOf<TValue>(this.values, value, 0, this._size);
}
//IDictionary<TKey, TValue>接口方法实现
public bool Remove(TKey key)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
this.RemoveAt(num1);
}
return (num1 >= 0);
}
//移除指定索引元素
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
throw new ArgumentOutOfRangeException("index", "Index out of range");
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, (int)(index + 1), this.keys, index,
(int)(this._size - index));
Array.Copy(this.values, (int)(index + 1), this.values, index,
(int)(this._size - index));
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
//排序
public void Sort()
{
// 检查是否跟现有排序方向相同.
if (this._currentSortDirection !=
this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
//剪除多余空间
public void TrimExcess()
{
int num1 = (int)(this.keys.Length * 0.9);
if (this._size < num1)
{
this.Capacity = this._size;
}
}
//获取指定键的值
public bool TryGetValue(TKey key, out TValue value)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
value = this.values[num1];
return true;
}
value = default(TValue);
return false;
}
#endregion // Public Methods
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
4.8 反转Sorted List里的内容
问题
您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedList和SortedList<T>类原来的功能。无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表。
解决方案
ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。
在实例化ReversibleSortedList<TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:
ReversibleSortedList<int, string> rsl = new ReversibleSortedList<int, string>();
rsl.Add(2, "2");
rsl.Add(5, "5");
rsl.Add(3, "3");
rsl.Add(1, "1");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
列表输出显示为按升序排序(默认):
1 1 2 2 3 3 5 5现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Descending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
Compare方法使用了SortDirectionComparer<T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList<TKey, TValue>的内部类SortDirectionComparer<T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList<TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:
public void Sort()
{
//检查是否跟现有排序方向相同.
if (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
讨论
例4-3是ReversibleSortedList<TKey, TValue>类的所有代码:
(译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)
例4-3 ReversibleSortedList类
[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
public class ReversibleSortedList<TKey, TValue> :
IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>,
IDictionary, ICollection, IEnumerable
{
SortDirectionComparer类定义#region SortDirectionComparer类定义
public class SortDirectionComparer<T> : IComparer<T>
{ //ListSortDirection 枚举,有两个值:
//Ascending按升序排列,Descending按降序排列
private System.ComponentModel.ListSortDirection _sortDir;
//构造方法
public SortDirectionComparer()
{ //默认为升序
_sortDir = ListSortDirection.Ascending;
}
//重载构造方法
public SortDirectionComparer(ListSortDirection sortDir)
{
_sortDir = sortDir;
}
//排序方向属性
public System.ComponentModel.ListSortDirection SortDirection
{
get { return _sortDir; }
set { _sortDir = value; }
}
//实现IComparer<T>接口的方法
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// If order is DESC, reverse this comparison.
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
#endregion // SortDirectionComparer
构造方法#region 构造方法
//类型构造器
static ReversibleSortedList()
{
ReversibleSortedList<TKey, TValue>.emptyKeys = new TKey[0];
ReversibleSortedList<TKey, TValue>.emptyValues = new TValue[0];
}
//无参构造方法
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
//用于指定排序方向的构造方法
public ReversibleSortedList(SortDirectionComparer<TKey> comparer)
: this()
{
if (comparer != null)
{
this._sortDirectionComparer = comparer;
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
}
//用于指定字典的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary)
: this(dictionary, (SortDirectionComparer<TKey>)null)
{
}
//用于指定列表容量的构造方法
public ReversibleSortedList(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException(
"capacity", "Non-negative number required");
}
this.keys = new TKey[capacity];
this.values = new TValue[capacity];
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
//用于指定字典和排序方向的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary,
SortDirectionComparer<TKey> comparer)
: this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values,
this._sortDirectionComparer);
this._size = dictionary.Count;
}
//用于指定容量和排序方向的构造方法
public ReversibleSortedList(int capacity, SortDirectionComparer<TKey> comparer)
: this(comparer)
{
this.Capacity = capacity;
}
#endregion //CTORS
公有方法#region 公有方法
//添加元素
public void Add(TKey key, TValue value)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 >= 0)
{
throw new ArgumentException("Attempting to add duplicate");
}
this.Insert(~num1, key, value);
}
//ICollection<KeyValuePair<TKey, TValue>>接口方法实现
public void Clear()
{
this.version++;
Array.Clear(this.keys, 0, this._size);
Array.Clear(this.values, 0, this._size);
this._size = 0;
}
//判断是否包含指定键
public bool ContainsKey(TKey key)
{
return (this.IndexOfKey(key) >= 0);
}
//判断是否包含指定值
public bool ContainsValue(TValue value)
{
return (this.IndexOfValue(value) >= 0);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new ReversibleSortedList<TKey, TValue>.Enumerator<TKey, TValue>(
this);
}
//查找指定键
public int IndexOfKey(TKey key)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 < 0)
{
return -1;
}
return num1;
}
//查找指定值
public int IndexOfValue(TValue value)
{
return Array.IndexOf<TValue>(this.values, value, 0, this._size);
}
//IDictionary<TKey, TValue>接口方法实现
public bool Remove(TKey key)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
this.RemoveAt(num1);
}
return (num1 >= 0);
}
//移除指定索引元素
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
throw new ArgumentOutOfRangeException("index", "Index out of range");
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, (int)(index + 1), this.keys, index,
(int)(this._size - index));
Array.Copy(this.values, (int)(index + 1), this.values, index,
(int)(this._size - index));
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
//排序
public void Sort()
{
// 检查是否跟现有排序方向相同.
if (this._currentSortDirection !=
this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
//剪除多余空间
public void TrimExcess()
{
int num1 = (int)(this.keys.Length * 0.9);
if (this._size < num1)
{
this.Capacity = this._size;
}
}
//获取指定键的值
public bool TryGetValue(TKey key, out TValue value)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
value = this.values[num1];
return true;
}
value = default(TValue);
return false;
}
#endregion // Public Methods
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
4.8 反转Sorted List里的内容
问题
您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedList和SortedList<T>类原来的功能。无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表。
解决方案
ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。
在实例化ReversibleSortedList<TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:
ReversibleSortedList<int, string> rsl = new ReversibleSortedList<int, string>();
rsl.Add(2, "2");
rsl.Add(5, "5");
rsl.Add(3, "3");
rsl.Add(1, "1");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
列表输出显示为按升序排序(默认):
1 1 2 2 3 3 5 5现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Descending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
Compare方法使用了SortDirectionComparer<T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList<TKey, TValue>的内部类SortDirectionComparer<T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList<TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:
public void Sort()
{
//检查是否跟现有排序方向相同.
if (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
讨论
例4-3是ReversibleSortedList<TKey, TValue>类的所有代码:
(译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)
例4-3 ReversibleSortedList类
[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
public class ReversibleSortedList<TKey, TValue> :
IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>,
IDictionary, ICollection, IEnumerable
{
SortDirectionComparer类定义#region SortDirectionComparer类定义
public class SortDirectionComparer<T> : IComparer<T>
{ //ListSortDirection 枚举,有两个值:
//Ascending按升序排列,Descending按降序排列
private System.ComponentModel.ListSortDirection _sortDir;
//构造方法
public SortDirectionComparer()
{ //默认为升序
_sortDir = ListSortDirection.Ascending;
}
//重载构造方法
public SortDirectionComparer(ListSortDirection sortDir)
{
_sortDir = sortDir;
}
//排序方向属性
public System.ComponentModel.ListSortDirection SortDirection
{
get { return _sortDir; }
set { _sortDir = value; }
}
//实现IComparer<T>接口的方法
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// If order is DESC, reverse this comparison.
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
#endregion // SortDirectionComparer
构造方法#region 构造方法
//类型构造器
static ReversibleSortedList()
{
ReversibleSortedList<TKey, TValue>.emptyKeys = new TKey[0];
ReversibleSortedList<TKey, TValue>.emptyValues = new TValue[0];
}
//无参构造方法
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
//用于指定排序方向的构造方法
public ReversibleSortedList(SortDirectionComparer<TKey> comparer)
: this()
{
if (comparer != null)
{
this._sortDirectionComparer = comparer;
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
}
//用于指定字典的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary)
: this(dictionary, (SortDirectionComparer<TKey>)null)
{
}
//用于指定列表容量的构造方法
public ReversibleSortedList(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException(
"capacity", "Non-negative number required");
}
this.keys = new TKey[capacity];
this.values = new TValue[capacity];
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
//用于指定字典和排序方向的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary,
SortDirectionComparer<TKey> comparer)
: this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values,
this._sortDirectionComparer);
this._size = dictionary.Count;
}
//用于指定容量和排序方向的构造方法
public ReversibleSortedList(int capacity, SortDirectionComparer<TKey> comparer)
: this(comparer)
{
this.Capacity = capacity;
}
#endregion //CTORS
公有方法#region 公有方法
//添加元素
public void Add(TKey key, TValue value)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 >= 0)
{
throw new ArgumentException("Attempting to add duplicate");
}
this.Insert(~num1, key, value);
}
//ICollection<KeyValuePair<TKey, TValue>>接口方法实现
public void Clear()
{
this.version++;
Array.Clear(this.keys, 0, this._size);
Array.Clear(this.values, 0, this._size);
this._size = 0;
}
//判断是否包含指定键
public bool ContainsKey(TKey key)
{
return (this.IndexOfKey(key) >= 0);
}
//判断是否包含指定值
public bool ContainsValue(TValue value)
{
return (this.IndexOfValue(value) >= 0);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new ReversibleSortedList<TKey, TValue>.Enumerator<TKey, TValue>(
this);
}
//查找指定键
public int IndexOfKey(TKey key)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 < 0)
{
return -1;
}
return num1;
}
//查找指定值
public int IndexOfValue(TValue value)
{
return Array.IndexOf<TValue>(this.values, value, 0, this._size);
}
//IDictionary<TKey, TValue>接口方法实现
public bool Remove(TKey key)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
this.RemoveAt(num1);
}
return (num1 >= 0);
}
//移除指定索引元素
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
throw new ArgumentOutOfRangeException("index", "Index out of range");
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, (int)(index + 1), this.keys, index,
(int)(this._size - index));
Array.Copy(this.values, (int)(index + 1), this.values, index,
(int)(this._size - index));
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
//排序
public void Sort()
{
// 检查是否跟现有排序方向相同.
if (this._currentSortDirection !=
this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
//剪除多余空间
public void TrimExcess()
{
int num1 = (int)(this.keys.Length * 0.9);
if (this._size < num1)
{
this.Capacity = this._size;
}
}
//获取指定键的值
public bool TryGetValue(TKey key, out TValue value)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
value = this.values[num1];
return true;
}
value = default(TValue);
return false;
}
#endregion // Public Methods
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
4.8 反转Sorted List里的内容
问题
您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedList和SortedList<T>类原来的功能。无论是SortedList还是泛型SortedList<T>类都直接提供了完成这个功能的方法而又不需要重填列表。
解决方案
ReversibleSortedList<TKey, TValue>类提供了这些功能,它基于SortedList<TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。
在实例化ReversibleSortedList<TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:
ReversibleSortedList<int, string> rsl = new ReversibleSortedList<int, string>();
rsl.Add(2, "2");
rsl.Add(5, "5");
rsl.Add(3, "3");
rsl.Add(1, "1");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
列表输出显示为按升序排序(默认):
1 1 2 2 3 3 5 5现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Descending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
Compare方法使用了SortDirectionComparer<T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList<TKey, TValue>的内部类SortDirectionComparer<T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList<TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:
public void Sort()
{
//检查是否跟现有排序方向相同.
if (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
讨论
例4-3是ReversibleSortedList<TKey, TValue>类的所有代码:
(译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)
例4-3 ReversibleSortedList类
[Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
public class ReversibleSortedList<TKey, TValue> :
IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>,
IDictionary, ICollection, IEnumerable
{
SortDirectionComparer类定义#region SortDirectionComparer类定义
public class SortDirectionComparer<T> : IComparer<T>
{ //ListSortDirection 枚举,有两个值:
//Ascending按升序排列,Descending按降序排列
private System.ComponentModel.ListSortDirection _sortDir;
//构造方法
public SortDirectionComparer()
{ //默认为升序
_sortDir = ListSortDirection.Ascending;
}
//重载构造方法
public SortDirectionComparer(ListSortDirection sortDir)
{
_sortDir = sortDir;
}
//排序方向属性
public System.ComponentModel.ListSortDirection SortDirection
{
get { return _sortDir; }
set { _sortDir = value; }
}
//实现IComparer<T>接口的方法
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// If order is DESC, reverse this comparison.
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
#endregion // SortDirectionComparer
构造方法#region 构造方法
//类型构造器
static ReversibleSortedList()
{
ReversibleSortedList<TKey, TValue>.emptyKeys = new TKey[0];
ReversibleSortedList<TKey, TValue>.emptyValues = new TValue[0];
}
//无参构造方法
public ReversibleSortedList()
{
this.keys = ReversibleSortedList<TKey, TValue>.emptyKeys;
this.values = ReversibleSortedList<TKey, TValue>.emptyValues;
this._size = 0;
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
//用于指定排序方向的构造方法
public ReversibleSortedList(SortDirectionComparer<TKey> comparer)
: this()
{
if (comparer != null)
{
this._sortDirectionComparer = comparer;
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
}
//用于指定字典的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary)
: this(dictionary, (SortDirectionComparer<TKey>)null)
{
}
//用于指定列表容量的构造方法
public ReversibleSortedList(int capacity)
{
if (capacity < 0)
{
throw new ArgumentOutOfRangeException(
"capacity", "Non-negative number required");
}
this.keys = new TKey[capacity];
this.values = new TValue[capacity];
this._sortDirectionComparer = new SortDirectionComparer<TKey>();
this._currentSortDirection = _sortDirectionComparer.SortDirection;
}
//用于指定字典和排序方向的构造方法
public ReversibleSortedList(IDictionary<TKey, TValue> dictionary,
SortDirectionComparer<TKey> comparer)
: this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
throw new ArgumentNullException("dictionary");
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values,
this._sortDirectionComparer);
this._size = dictionary.Count;
}
//用于指定容量和排序方向的构造方法
public ReversibleSortedList(int capacity, SortDirectionComparer<TKey> comparer)
: this(comparer)
{
this.Capacity = capacity;
}
#endregion //CTORS
公有方法#region 公有方法
//添加元素
public void Add(TKey key, TValue value)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 >= 0)
{
throw new ArgumentException("Attempting to add duplicate");
}
this.Insert(~num1, key, value);
}
//ICollection<KeyValuePair<TKey, TValue>>接口方法实现
public void Clear()
{
this.version++;
Array.Clear(this.keys, 0, this._size);
Array.Clear(this.values, 0, this._size);
this._size = 0;
}
//判断是否包含指定键
public bool ContainsKey(TKey key)
{
return (this.IndexOfKey(key) >= 0);
}
//判断是否包含指定值
public bool ContainsValue(TValue value)
{
return (this.IndexOfValue(value) >= 0);
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new ReversibleSortedList<TKey, TValue>.Enumerator<TKey, TValue>(
this);
}
//查找指定键
public int IndexOfKey(TKey key)
{
if (key.Equals(null))
{
throw new ArgumentNullException("key");
}
int num1 = Array.BinarySearch<TKey>(this.keys, 0, this._size, key,
this._sortDirectionComparer);
if (num1 < 0)
{
return -1;
}
return num1;
}
//查找指定值
public int IndexOfValue(TValue value)
{
return Array.IndexOf<TValue>(this.values, value, 0, this._size);
}
//IDictionary<TKey, TValue>接口方法实现
public bool Remove(TKey key)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
this.RemoveAt(num1);
}
return (num1 >= 0);
}
//移除指定索引元素
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
throw new ArgumentOutOfRangeException("index", "Index out of range");
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, (int)(index + 1), this.keys, index,
(int)(this._size - index));
Array.Copy(this.values, (int)(index + 1), this.values, index,
(int)(this._size - index));
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
//排序
public void Sort()
{
// 检查是否跟现有排序方向相同.
if (this._currentSortDirection !=
this._sortDirectionComparer.SortDirection)
{
// 如果不同,则进行反转.
Array.Reverse(this.keys, 0, this._size);
Array.Reverse(this.values, 0, this._size);
// 设置当前排序.
this._currentSortDirection = this._sortDirectionComparer.SortDirection;
}
}
//剪除多余空间
public void TrimExcess()
{
int num1 = (int)(this.keys.Length * 0.9);
if (this._size < num1)
{
this.Capacity = this._size;
}
}
//获取指定键的值
public bool TryGetValue(TKey key, out TValue value)
{
int num1 = this.IndexOfKey(key);
if (num1 >= 0)
{
value = this.values[num1];
return true;
}
value = default(TValue);
return false;
}
#endregion // Public Methods
这一次,输出为降序:
5 5 3 3 2 21 1
当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。
rsl.Add(4, "4");
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
// 转换排序方向.
rsl.Comparer.SortDirection = ListSortDirection.Ascending;
// 重排列表.
rsl.Sort();
foreach (KeyValuePair<int, string> kvp in rsl)
{
Debug.WriteLine("t" + kvp.Key + "t" + kvp.Value);
}
可以看到新项即按降序也按升序排列:
5 5 4 4 3 3 2 2 1 1 1 1 2 2 3 3 4 4 5 5
ReversibleSortedList<TKey, TValue>包含一个实现了IComparer<T>接口的嵌套类SortDirectionComparer<T>。这个类可以在“讨论”这一节中的ReversibleSortedList<TKey, TValue>代码中看到。一个实现了IComparer<T>接口的类可以做为ReversibleSortedList<TKey, TValue>构造方法的参数来改变默认的排序。IComparer<T>接口实现了Compare方法:
class Program
{
public int Compare(T lhs, T rhs)
{
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
int compareResult =
lhs.ToString().CompareTo(rhs.ToString());
// 如果为降序, 则反转
if (SortDirection == ListSortDirection.Descending)
compareResult *= -1;
return compareResult;
}
}
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数