使用附加增量(即 NewObject_1)重命名复制的对象



我目前正在使用Treeview控件开发WinForms应用程序。我添加了一个复制机制来复制当前选定的Treenode。复制的Treenode对象的名称应通过以下方式与原始Treenode不同:"一个节点","aNode_1","aNode_2"。

感觉Regex是要走的路。

这是我到目前为止得到的:

string theNameToBe = "aName";
List<string> theAlreadyInUseNames   // Filled beforehand
int i = 1;
do
{
    // ToDo: Use Regex to get XXXXX_1 -> XXXXX_2 as a possible name instead of XXXXX_1_1
    Regex aPossibleNewNameRegex = new Regex( String.Format("^{0}[_]\d+$", theNameToBe),RegexOptions.IgnoreCase);
    // This does not take a previously created XXXXX_1 into account and continues to attach "_1"s to the string
    string thePossibleNewName = String.Format( theNameToBe + "_{0}", i );
    if ( !theAlreadyInUseNames.Any( s => s.Equals( thePossibleNewName, StringComparison.OrdinalIgnoreCase ) ) )
    {
        theNextAvailableName = thePossibleNewName;
        break;
    }
    i++;
} while ( i < int.MaxValue );

这只会获得后续名称,如"aNode"、"aNode_1"、"aNode_1_1"、...等等。

你能帮助我解决我在C#中缺乏手语正则表达式的专业知识吗?

编辑以澄清:应确定下一个可用的空白点。稍后删除其中一个节点/名称时,有一个空位。因此,如果只有字符串"aName","aName_1"和"aName_3"存在,则"aName_2"是正确的发现。

可以像

var selected = "node_3";
var names = new[] { "node_1", "node_3" };
var prefix = selected.Substring(0, selected.IndexOf('_') + 1);
var number = 1;
string name; // result
do
    name = prefix + number++;
while (names.Contains(name));

我可能已经找到了满足要求的解决方案。这是初稿,可能会在一轮单元测试和现实生活场景后更新。而且总是有可能这个版本对于工作来说是复杂的,Sinatrs的苗条方法可能就足够了。

    static void Main( string[] args )
    {
        List<string> theAlreadyInUseNames = new List<string>();
        theAlreadyInUseNames.Add( "aName" );
        theAlreadyInUseNames.Add( "aName_1" );
        theAlreadyInUseNames.Add( "aName_2" );
        theAlreadyInUseNames.Add( "aName_3" );
        theAlreadyInUseNames.Add( "aName_4" );
        theAlreadyInUseNames.Add( "aName_5" );
        theAlreadyInUseNames.Add( "aName_7" );
        theAlreadyInUseNames.Add( "aName_2_1" );
        theAlreadyInUseNames.Add( "aName_2_3" );
        string theNameToBe0 = "aName";
        string theNameToBe1 = "aName_2";
        string theNameToBe2 = "aName_2_1";
        List<string> namesToBe = new List<string>();
        namesToBe.Add( theNameToBe0 );
        namesToBe.Add( theNameToBe1 );
        namesToBe.Add( theNameToBe2 );
        string[] splits;
        char[] charSeparators = new char[] { '_' };
        string theNewNameToBe1 = string.Empty;
        string theNextAvailableName = String.Empty;
        foreach ( var item in namesToBe )
        {
            splits = item.Split( charSeparators, StringSplitOptions.RemoveEmptyEntries );

            if ( splits.Length > 1 )
            {
                int theNumber = Convert.ToInt32( splits.Last() );
                theNewNameToBe1 = splits.ElementAt( 0 );
                for ( int i = 1; i < splits.Length - 1; i++ )
                {
                    theNewNameToBe1 = theNewNameToBe1 + "_" + splits.ElementAt( i );
                }
                int counter = 1;
                string theActualNewName = string.Empty;
                do
                {
                    theActualNewName = theNewNameToBe1 + "_" + ( theNumber + counter );
                    if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
                    {
                        theNextAvailableName = theActualNewName;
                        break;
                    }
                    counter++;
                } while ( counter < int.MaxValue );
            }
            else if ( splits.Length == 1 )
            {
                    int counter = 1;
                    string theActualNewName = string.Empty;
                    do
                    {
                        theActualNewName = theNameToBe + "_" + ( counter );
                        if ( !theAlreadyInUseNames.Any( s => s.Equals( theActualNewName, StringComparison.OrdinalIgnoreCase ) ) )
                        {
                            theNextAvailableName = theActualNewName;
                            break;
                        }
                        counter++;
                    } while ( counter < int.MaxValue );
            }
            else
            {
                throw new ArgumentException();
            }
        }
    }

最新更新