C# 在字符串列表中搜索文件名匹配并替换为新文件路径

C# 在字符串列表中搜索文件名匹配并替换为新文件路径,c#,.net,list,C#,.net,List,我有一个名为Filelist的列表,它包含文件的完整路径。我有另一个名为optimizelist的List也包含文件路径。我正在检查Filelist中是否包含相同的文件optimizelist;如果是,则将文件列表中的相应元素替换为优化列表中的元素 int x = 0; foreach (string file in optimizelist) { for (int i = 0; i < Filelist.Count; i++) { if (Path.Ge

我有一个名为
Filelist
列表,它包含文件的完整路径。我有另一个名为
optimizelist
List
也包含文件路径。我正在检查
Filelist
中是否包含相同的文件
optimizelist
;如果是,则将
文件列表
中的相应元素替换为
优化列表
中的元素

int x = 0;

foreach (string file in optimizelist)
{
    for (int i = 0; i < Filelist.Count; i++)
    {
        if (Path.GetFileName(file) == Path.GetFileName(Filelist[i]))
        {
            Filelist.RemoveAt(x);
            Filelist.Add(file);

            break;
        }
     }

     x++;
}
intx=0;
foreach(优化列表中的字符串文件)
{
for(int i=0;i
但替换不恰当,存在重复和缺失条目。
我做错了什么?请给出建议。

您正在更改正在迭代的列表,这可能会导致意外行为。您可以通过向后迭代来避免意外(因为更改是在当前索引和列表末尾进行的,所以永远不会在较低的索引中进行)

编辑:您可能还想删除“break”语句。它会阻止您的代码迭代完整列表。

在枚举列表时,您正在删除(在中间)和添加(在末尾)。这不是一个好主意,导致了这个问题。我建议采用这种方法来替换文件:

var fileNameLookup = optimizelist.ToLookup(f => Path.GetFileName(f));
for (int i = 0; i < Filelist.Count; i++)
{
    string fileName = Path.GetFileName(Filelist[i]);
    var optimizedFile = fileNameLookup[fileName].FirstOrDefault();
    if(optimizedFile != null)
        Filelist[i] = optimizedFile;
}
var fileNameLookup=optimizelist.ToLookup(f=>Path.GetFileName(f));
for(int i=0;i
除了Peter M。回答:如果您在
优化列表中没有重复项,您可以尝试使用字典:

//键-要查找的内容(没有目录的文件名,例如“abc.txt”)
//值-要替换的内容(完整路径名,例如“c:\test\abc.txt”)
//StringComparer.OrdinalIgnoreCase-不区分大小写的键,即“abc.txt”==“abc.txt”
字典替换=优化列表
.ToDictionary(项=>Path.GetFileName(项),
项目=>项目,
普通木糖酶);
for(int i=0;i文件列表[i]=最佳文件;//谢谢这似乎已经解决了这个问题。该列表不包含重复条目,并且已预筛选。因此我认为需要中断。。我想,你觉得怎么样?@techno如果你确定没有重复的,我想你可以保留中断声明。谢谢你的回答,optimizelist不包含重复项。您对break语句有何看法?@techno:在我的版本中,它应该是任何
break
:您应该扫描
文件列表中的每个
文件
,并在需要时替换它。如果您在
文件列表中第一个可能的文件中放置仅中断
将得到优化(假设您有
文件列表[a,b,c,d]
;如果没有
中断
,您将得到
文件列表[a,b,c,d]
-替换两个文件,并使用
中断
文件列表[a,b,c,d]
-仅第一个)@techno:仅在我的代码中。在您的代码中,如果
文件列表
没有duplicates@techno:刚刚编辑了答案,向您展示了一种更好、更高效的方法,但为什么要替换您?请执行删除+添加?您只需执行
Filelist[x]=file@Evk好的…谢谢你的建议。
var fileNameLookup = optimizelist.ToLookup(f => Path.GetFileName(f));
for (int i = 0; i < Filelist.Count; i++)
{
    string fileName = Path.GetFileName(Filelist[i]);
    var optimizedFile = fileNameLookup[fileName].FirstOrDefault();
    if(optimizedFile != null)
        Filelist[i] = optimizedFile;
}
// key    - what to find (file name without directory, e.g. "abc.txt")
// value  - what to substitute (full path name, e.g. "c:\test\abc.txt") 
// StringComparer.OrdinalIgnoreCase - case insensitive keys, i.e. "abc.txt" == "ABC.txt"
Dictionary<string, string> substitutes = optimizelist
  .ToDictionary(item => Path.GetFileName(item),
                item => item,
                StringComparer.OrdinalIgnoreCase);

for (int i = 0; i < Filelist.Count; i++)
  // if we have a substitution (i.e. a better file path)...
  if (optimizelist.TryGetValue(Path.GetFileName(Filelist[i]), out var optimalFile))
    Filelist[i] = optimalFile; // <- substitute with optimalFile