生成唯一列表变量

时间:2016-03-09 13:26:56

标签: c# string list

我有一个C#程序,其中有一个唯一字符串的列表(List<string>)。这些字符串代表不同案例的名称。什么是重要的并不重要。但它们必须是独一无二的。

cases = new List<string> { "case1", "case3", "case4" }

有时我会将以文本格式保存的一些案例读入我的程序。有时,存储在文件中的案例与我程序中的案例具有相同的名称。我必须重命名这个新案例。可以说我从文件加载的案例名称是case1。

但问题是。如何在不添加大型随机字符串的情况下重命名。在我的情况下,理想情况下它应该被称为case2,我找不到任何可以做到这一点的好算法。我想找到我能添加的最小数字,使其独一无二。

3 个答案:

答案 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
}