我已经建立了一种比较两个文件目录中文件的方法,如果存在以布尔形式重复的文件,它将返回。但是,实际上希望它返回文件名或文件在其数组中的索引,这样我就可以删除该文件,因此将文件移到一个目录时它们不会造成任何麻烦。我试图将“ ==” compare语句转换为一个字符串,希望它能给出文件名,但是我忘了,因为它是布尔运算,只会返回true或false。
static public string ModFileDupilcate(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
string NoDuplicateMods = "There are no duplicate mods";
foreach (var ModInDownloadDirectory in SimsModDownloadDirectory)
{
foreach (var ModInModsDirectory in SimsModsDirectory)
{
if (ModInDownloadDirectory == ModInModsDirectory)
{
string DuplicateMod = (ModInDownloadDirectory == ModInModsDirectory).ToString();
return DuplicateMod;
}
else
{
return NoDuplicateMods;
}
}
}
return NoDuplicateMods;
}
答案 0 :(得分:3)
您可以通过以下方式获取匹配字符串的索引
var result = SimsModDownloadDirectory.Select((x, i) =>
{return (SimsModsDirectory.Contains(x) ? i :-1);})
.Where(x => x != -1);
foreach(int index in result)
Console.WriteLine(index);
想法如下:
用第一个列表中的所有字符串(x)进行枚举,并带有重载,如果第二个列表中包含了枚举字符串,则重载也为我们提供了枚举字符串(i)的索引,否则返回-1。最后,使用Select仅提取非-1值的地方
当然,仅返回重复项的名称要简单得多
var result = SimsModDownloadDirectory.Intersect(SimsModsDirectory);
foreach(string name in result)
Console.WriteLine(name);
这些方法基于要比较的两个字符串之间的精确匹配。因此,字符串“ Steve”将与字符串“ steve”不匹配。
如果您的要求是忽略比较中的大小写,则可以更改为
var result = SimsModDownloadDirectory.Select((x, i) =>
{
return (SimsModsDirectory.Contains(x,
StringComparer.CurrentCultureIgnoreCase) ? i :-1);
}).Where(x => x != -1);
或到
var result = SimsModDownloadDirectory.Intersect(SimsModsDirectory,
StringComparer.CurrentCultureIgnoreCase);
答案 1 :(得分:1)
代码中的else就是问题。
示例代码(未经测试)
static public string ModFileDupilcate(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
string NoDuplicateMods = "There are no duplicate mods";
foreach (var ModInDownloadDirectory in SimsModDownloadDirectory)
{
foreach (var ModInModsDirectory in SimsModsDirectory)
{
if (ModInDownloadDirectory == ModInModsDirectory)
{
return ModInModsDirectory;
}
}
}
return NoDuplicateMods;
}
以上内容仅返回第一个重复项。对于所有重复项,您必须维护一个列表并在最后将其返回
static public List<string> ModFileDupilcate(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
var duplicateDirs = new List<string>();
foreach (var ModInDownloadDirectory in SimsModDownloadDirectory)
{
foreach (var ModInModsDirectory in SimsModsDirectory)
{
if (ModInDownloadDirectory == ModInModsDirectory)
{
duplicateDirs.Add(ModInModsDirectory);
}
}
}
return duplicateDirs;
}
答案 2 :(得分:1)
我不确定您要达到什么目标。您的代码没有告诉我们返回值应该是什么。如果要告诉呼叫者“文件名不存在/不重复”,则可以轻松返回bool
。如果要返回“重复文件名”,则应返回string[]
或FileInfo[]
或IReadOnlyCollection<string>
或类似的名称。返回集合或数组的好处是,调用者可以通过检查返回值的Length
/ Count
来轻松查看是否存在重复项。
使用嵌套的for
循环会导致O(n * m)的性能下降。使用HashSet
或LINQ的Intersect
方法,您可以轻松实现O(n + m)的目标:
public static IReadOnlyList<string> FindDuplicateModFiles(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
var set = new HashSet<string>(SimsModDownloadDirectory);
var result = new List<string>();
foreach (string file in SimsModsDirectory)
{
if (set.Contains(file))
result.Add(file);
}
return result.AsReadOnly();
}
或使用LINQ:
public static IEnumerable<string> FindDuplicateModFiles2(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
return SimsModDownloadDirectory.Intersect(SimsModsDirectory);
}
如果要从第一个集合中删除重复项,最好的选择是LINQ的Except
方法:
public static IEnumerable<string> GetNonDuplicatesInFirst(string[] SimsModDownloadDirectory, string[] SimsModsDirectory)
{
return SimsModDownloadDirectory.Except(SimsModsDirectory);
}
答案 3 :(得分:0)
static public IEnumerable<string> ModFileDupilcate(string[] SimsModDownloadDirectory,
string[] SimsModsDirectory)
{
var result = SimsModDownloadDirectory.Select((x, i) =>
SimsModsDirectory.Contains(x) ? x : string.Empty).
Where(x => !string.IsNullOrEmpty(x));
return result;
}
调用方法如:
var resultOfDublicateFiles = ModFileDupilcate(SimsModDownloadDirectory,SimsModsDirectory);
或
public static bool ModFileDupilcate(string[] SimsModDownloadDirectory,
List<string> SimsModsDirectory,out List<string> dublicatedFiles)
{
dublicatedFiles = new List<string>();
foreach (var ModInDownloadDirectory in SimsModDownloadDirectory)
{
foreach (var ModInModsDirectory in SimsModsDirectory)
{
if (ModInDownloadDirectory == ModInModsDirectory)
{
dublicatedFiles.Add(ModInModsDirectory);
}
}
}
return dublicatedFiles.Count > 0;
}
调用方法如:
List<string> dublicatedFiles;
bool hasDublicatedFiles= ModFileDupilcate(new string["a","b","c"],new string["b","c","d","f"],out dublicatedFiles);