Nils
Nils

Reputation: 469

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?

Upvotes: 3

Views: 442

Answers (4)

RoadRunner
RoadRunner

Reputation: 26315

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

Upvotes: 3

Anton
Anton

Reputation: 841

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

Upvotes: 4

MarcE
MarcE

Reputation: 3731

Something like this?

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

Upvotes: 4

Babak Naffas
Babak Naffas

Reputation: 12561

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

Upvotes: 2

Related Questions