简体   繁体   中英

Is there a way to combine List.Contains() and string.StartsWith()?

I have a list of filenames where i want to check if there are duplicate filenames different extensions

Example: Randomfilename.xlsx and Randomfilename.pptx

My approach looks like this:

string tempFileName = originalFilename.Remove(file.LastIndexOf("."));
if (allFilesInDirectory.Contains(  string that starts with tempFileName  ))

But i dont think there is this exact function. Whats the workaround to this?

You can use LINQ Any function

allFilesInDirectory.Any(s => s.StartsWith(tempFileName))

Or if you want to find the element

var file = allFilesInDirectory.FirstOrDefault(s => s.StartsWith(tempFileName));

EDIT

Without LINQ

allFilesInDirectory.FindAll(s => s.StartsWith(tempFileName)).Count > 0

or

var fileName = allFilesInDirectory.Find(s => s.StartsWith(tempFileName));

Something like this?

var filenamesGrouped = allFilesInDirectory.GroupBy(x => Path.GetFileNameWithoutExtension(x));
var duplicates = filenamesGrouped.Count() > 1;

You could use LINQ here to group all files with the same filename, and filter groups with more than one duplicate filename:

var duplicates = Directory
    .GetFiles(path)
    .GroupBy(f => Path.GetFileNameWithoutExtension(f))
    .Where(grp => grp.Count() > 1);

The above uses Directory.GetFiles() to list the files in a directory, Enumerable.GroupBy() to group the files without the extension, which can be extracted with Path.GetFileNameWithoutExtension() . Then you can filter the groups with Enumerable.Where() .

Demo:

var duplicates = Directory
    .GetFiles(path)
    .GroupBy(f => Path.GetFileNameWithoutExtension(f))
    .Where(grp => grp.Count() > 1);

foreach (var fileGroup in duplicates)
{
    Console.WriteLine($"{fileGroup.Key} : {string.Join(", ", fileGroup.Select(f => Path.GetFileName(f)))}");
}

Output:

Randomfilename : Randomfilename.csv, Randomfilename.txt

If you want to check against a specific filename like in your question:

var duplicates = Directory
    .GetFiles(path)
    .Where(f => Path.GetFileNameWithoutExtension(f) == "Randomfilename");

if (duplicates.Count() > 1)
{
    // We found duplicates
}

Which we can wrap into a method as well:

private static bool FileHasDuplicates(string path, string filename)
{
    return Directory
        .GetFiles(path)
        .Where(f => Path.GetFileNameWithoutExtension(f) == filename)
        .Count() > 1;
}

If you want to scan all sub directories of a given directory as well, then you can use Directory.EnumerateFiles() :

var duplicates = Directory
    .EnumerateFiles(path, "*", SearchOption.AllDirectories)
    .GroupBy(f => Path.GetFileNameWithoutExtension(f))
    .Where(grp => grp.Count() > 1);

You can sort allFilesInDirectory and iterate. Check for elements next to each other in the sorted list for matching file names (without extension).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM