我的C#程序允许用户按优先级数字对项目进行排名。我编写了一个例程,当用户修改项目的排名时,该例程会按排名自动调整项目。因此,当项目排名优先级3变为1时,例程将对前3个项目进行调整。那些先前排名为1,2的人排名第2,3位。同样,当优先级1项目成为优先级3时,那些排名为2,3的成为1,2。
现有的集合类是否内置了此功能?如果是这样,代码样本也将受到赞赏。
答案 0 :(得分:4)
C#有一个SortedSet<T>
集合,可以使用用户提供的自定义IComparer<T>
进行排序。
但是,该设置将不对您集合中已有项目的更改做出反应,即如果您更改项目中已有项目的优先级,则不会移动该项目自动向上或向下。
您需要从SortedSet<T>
中删除该项目,更改其优先级,然后将其重新添加。这样,集合将把它放在新的位置,移动其他项目以适应变化:
SortedSet<Project> prioritizedProjects = new SortedSet<Project>(new CompareProjByPriority());
...
Project rePrioritize = ...;
prioritizedProjects.Remove(rePrioritize);
rePrioritize.Priority = 1;
prioritizedProjects.Add(rePrioritize);
答案 1 :(得分:1)
没有“理解”排名概念的内置集合。但是,如果排名是连续数字的虚构概念,那么简单的List<Project>
就可以:
List<Project> projects = GetProjects();
Project project = projects[2]; // grab project on rank 3 (index 2 since it's 0 based)
projects.RemoveAt(2); // pick it up
projects.Insert(0, project); // place the project in front of the first
这将允许用户“优先”项目。
但是,如果排名是Project
的属性,则需要手动更新每个受影响的元素;这不应该是内置集合的责任。
答案 2 :(得分:0)
您可以扩展一些集合,例如:通用列表来执行此操作
public static bool SetValue<T>(this List<T> collection, int oldValue, int newValue)
{
if ((Math.Min(newValue, oldValue) <= -1) ||
(Math.Max(newValue, oldValue) > collection.Count()))
{
return false;
}
if (newValue != oldValue)
{
var value = collection[oldValue];
collection.RemoveAt(oldValue);
if (newValue == collection.Count())
{
collection.Add(value);
}
else
{
collection.Insert(newValue, value);
}
}
return true;
}
之后你可以这样做:
var items = new List<char> { 'A', 'B', 'C' };
var start = string.Join(", ", items); //"A, B, C"
items.SetValue(2, 0);
var result = string.Join(", ", items); //"C, A, B"
它是2,0而不是3,1因为第一个元素是0而不是1。