我有一个C#程序,其中有一个唯一字符串的列表(List<string>
)。这些字符串代表不同案例的名称。什么是重要的并不重要。但它们必须是独一无二的。
cases = new List<string> { "case1", "case3", "case4" }
有时我会将以文本格式保存的一些案例读入我的程序。有时,存储在文件中的案例与我程序中的案例具有相同的名称。我必须重命名这个新案例。可以说我从文件加载的案例名称是case1。
但问题是。如何在不添加大型随机字符串的情况下重命名。在我的情况下,理想情况下它应该被称为case2,我找不到任何可以做到这一点的好算法。我想找到我能添加的最小数字,使其独一无二。
答案 0 :(得分:2)
解决方案非常简单。获取当前存储在列表中的最大案例数,按1递增并添加新值:
var max = myList.Max(x => Convert.ToInt32(x.Substring("case".Length))) + 1;
myList.Add("case" + max);
工作fiddle。
编辑:为了填写您馆藏中的任何“洞”,您可以使用:
var tmp = myList;
var firstIndex = Convert.ToInt32(myList[0].Substring("case".Length));
for(int i = firstIndex; i < tmp.Count; i++) {
var curIndex = Convert.ToInt32(myList[i].Substring("case".Length));
if (curIndex != i)
{
myList.Add("case" + (curIndex + 1));
break;
}
}
如果案例后面的数字等于列表中的索引,它会检查列表中的每个元素。循环在条件被破坏的第一个元素处停止,因此列表中有一个洞。
答案 1 :(得分:2)
我会使用只接受唯一值的HashSet
。
List<string> cases = new List<string>() { "case1", "case3", "case4" };
HashSet<string> hcases = new HashSet<string>(cases);
string Result = Enumerable.Range(1, 100).Select(x => "case" + x).First(x => hcases.Add(x));
// Result is "case2"
在此示例中,我尝试将1到100之间的元素添加到hashset并确定第一个成功Add()
答案 2 :(得分:2)
如果您有唯一字符串列表,请考虑使用HashSet<string>
。由于您希望增加数字听起来就像您实际应该使用自定义类而不是string
一样。一个包含名称和数字属性的。然后,您可以增加数字,如果您想要全名(或覆盖ToString
),请使用Name + Number
。
假设课程为Case
,您可以填写HashSet<Case>
。 HashSet.Add
会在重复项上返回false
。然后使用一个循环,增加数字直到可以添加。
这样的事情:
var cases = new HashSet<Case>();
// fill it ...
// later you want to add one from file:
while(!cases.Add(caseFromFile))
{
// you will get here if the set already contained one with this name+number
caseFromFile.Number++;
}
可能的实施:
public class Case
{
public string Name { get; set; }
public int Number { get; set; }
// other properties
public override string ToString()
{
return Name + Number;
}
public override bool Equals(object obj)
{
Case other = obj as Case;
if (other == null) return false;
return other.ToString() == this.ToString();
}
public override int GetHashCode()
{
return (ToString() ?? "").GetHashCode();
}
// other methods
}