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

Posted

技术标签:

【中文标题】重命名带有附加增量的复制对象(即 NewObject_1)【英文标题】:Rename copied objects with attached increment (i.e. NewObject_1) 【发布时间】:2016-05-30 19:37:06 【问题描述】:

我目前正在使用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”就是正确的发现。

【问题讨论】:

您是在重命名还是生成名称?因为生成就像$"name_i++"一样简单。 这是关于确定下一个可用位置。就像在删除 aName_2 之后,下一个复制的节点应该插入到 aName_1 和 aName_3 之间,而不是简单地添加另一个节点并将其命名为 aName_4。好点,谢谢。我会尝试在问题中澄清这一点。 问题不清楚。你有什么(举例)?你想得到什么? 经过一些删除、添加和复制后,假设条目列表如下:aNode、aNode_1、aDefaultNode、aNode_3、aNode_New 然后选择 aNode_1 并复制它。新名称应该是 aNode_2。我得到的是aNode_1_1。 【参考方案1】:

可以这么简单

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));

【讨论】:

【参考方案2】:

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

    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();
            
        
    

【讨论】:

以上是关于重命名带有附加增量的复制对象(即 NewObject_1)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用bat批处理或cmd,:将一个文件复制为“多个副本“(增量备份,自动重命名)到指定目录

如何用变量重命名对象的键? [复制]

在 TypeScript 中使用解构/扩展复制具有重命名属性的对象

如何使用 javascript /Angular 重命名现有对象键? [复制]

如何在mysql中重命名数据库? [复制]

使用增量索引重命名目录中的文件