0

I have a list of strings

var lsNameList = new List<string>();

that is a list of file names. I want to iterate over a collection of files checking the file names for matches. If there is a match then append on a number. the number will be increments in one. eg If filename is in the list then append on 1 so it will be filename1. If filename1 is in the list then change it to filename2 and so on.

foreach (var SourceFile in SourceFiles)
  if (lsNameList.Contains(SourceFile.Label.ToLower()))
     // Add the name to the list but with a number at the end

I have the iteration and filename checking done but I have a problem when the number runs into double digits

var sLastCharacter = SourceFile.Label[SourceFile.Label.Length - 1].ToString();
var iLast = StringToInt(sLastCharacter);

What if SourceFile.Label is filename10. The last digit will be 0 and we will start all over again causing a infinite loop.

Is there a way around this?

4

6 回答 6

1

不要只检查最后一个字符,而是检查整数并将其解析为int. 但我会在名称和数字之间使用分隔符,否则如果文件名本身以数字结尾,则会出现问题。

您可以使用带有自定义方法的 Linq 来增加数字并将其添加到另一个集合中:

IEnumerable<String> newPaths = SourceFiles
    .Select(sf => AddIncrementFileNameSuffix(sf.Label, lsNameList,"_"));

这就是所有的“魔法”

public static string AddIncrementFileNameSuffix(string path, IList<string> paths, string separator)
{
    string dir = Path.GetDirectoryName(path);
    string ext = Path.GetExtension(path);
    string fileName = Path.GetFileName(path);
    string[] tokens = fileName.Split(new[] { separator }, StringSplitOptions.None);

    int num = 0;
    int.TryParse(tokens.Last(), out num);

    var dups = paths.Where(n => n.Equals(path, StringComparison.OrdinalIgnoreCase));
    while (dups.Any())
    {
        path = Path.Combine(dir, tokens.First() + separator + ++num + ext);
    }

    paths.Add(path);
    return path;
}

演示

于 2012-12-13T10:45:51.593 回答
1

可以添加一个从文件末尾获取所有可能数字的函数:

所以(伪代码

var resultString = string.Empty;
for(int i=SourceFile.Label.Length - 1,i>=0;i--)
{
   var ch = SourceFile.Label[i];
   if(Char.IsNumber(ch))
     resultString = new string(ch) + resultString; //ADD IN FRONT
}

var iLast = StringToInt(resultString );

这是在您无法更改文件名格式的情况下。但是如果可以的话,你可以在数字前添加一个分隔符,比如“_”。因此,当您以此分割文件名时,您会知道右侧只有您需要的数字。

于 2012-12-13T10:13:29.957 回答
0

You could use LINQ to get a list of duplicates and then append the number to the end of each, like so:

var list = new List<string>() { "filename", "filename", "42", "another_file", "another_file" };
foreach (var item in list.Distinct().ToArray())
{
    var duplicates = list.Where(temp => temp == item).ToArray();
    for (int i = 0; i < duplicates.Length; i++)
    {
        duplicates[i] = string.Concat(item, (i + 1).ToString());
    }
 }
于 2012-12-13T10:23:12.450 回答
0
foreach (var SourceFile in SourceFiles)
{
    if (lsNameList.Contains(SourceFile.Label.ToLower()))
    {
        int fileNumber = 1;
        while (lsNameList.Contains((SourceFile.Label + fileNumber).ToLower()))
        {
           fileNumber++;
        }
        SourceFile.Label = SourceFile.Label + fileNumber;
    }
    lsNameList.Add(SourceFile.Label.ToLower());
}
于 2012-12-13T10:23:00.547 回答
0

不要假设只有字符串的最后一个字符是计数,您应该使用所有字符(您可以使用 Substring()),只忽略原始文件名。

于 2012-12-13T10:25:20.330 回答
0

尝试这个

foreach (var SourceFile in SourceFiles)
  if (lsNameList.Contains(SourceFile.Label.ToLower()))
  {
    int i = 1;
    while (lsNameList.Contains(SourceFile.Label.ToLower() + i.ToString()))
      i++;
    //add file with i as number
  }
于 2012-12-13T10:13:14.090 回答