Home > Mobile >  C# LINQ Queries - Get File Extension Type using IEnumerable<string>
C# LINQ Queries - Get File Extension Type using IEnumerable<string>

Time:11-24

I currently have a method that recursively enumerates all the files on my desktop and returns them as an IEnumerable<string>. What I am trying to now do is create a method that takes that IEnumerable<string> as the parameter and uses LINQ to group/order them by their file type. I am having trouble getting the file types. After experimenting, I have gotten this:

foreach(string file in files){
                FileInfo f = new FileInfo(file);
                Console.WriteLine(f.Extension);
                
}

I am able to get the extensions of all files, but cannot figure out how to get that information using a LINQ query

CodePudding user response:

You can use the GroupBy method:

var files = new[] { "c://file1.txt", "c://file2.png", "c://file3.txt" };
var groups = files.Select(f => new FileInfo(f)).GroupBy(file => file.Extension, file => file, 
    (key, g) => new
{
    Extension = key, Files = g.OrderBy(f => f.Name).ToList()
});
foreach (var fileGroup in groups)
{
    var ext = fileGroup.Extension;
    var innerFiles = fileGroup.Files;
    Console.WriteLine($@"Files with extension {ext}: {innerFiles.Count} files");
}

CodePudding user response:

To order :

List<string> listOrdered = files.OrderBy(x=>Path.GetExtension(x)).ToList()

To Group :

List<List<string>> listGroupped = files.GroupBy(x => Path.GetExtension(x))
            .Select(grp => grp.ToList())
            .ToList();

So you have a List of List<string>, in which you have all the files of the same extnsion.

CodePudding user response:

Instead of List<List<string>> I would suggest using a Dictionary<string, List<string>>.

Dictionary<string, List<string>> filesByExtension =
    files
        .GroupBy(file => Path.GetExtension(file))
        .ToDictionary(group => group.Key, group => group.ToList());

// Then later you can get all files with a specific extension.
List<string> executableFiles = filesByExtension[".exe"];

// If you want to display them, ordered by file extension.
foreach (string fileExtension in filesByExtensions.Keys.OrderBy(key => key))
{
    List<string> files = filesByExtensions[fileExtension];
}

CodePudding user response:

I'd use a lookup which is similar to a dictionary but the value is an enumerable, so you never get an exception if you ask for an item that is not contained(in this case a file-extension):

Get the desktop files:

var desktopFiles = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory))
    .EnumerateFiles()
    .Concat(new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory)).EnumerateFiles());

Here comes the important code, a one-liner:

var extensionLookup = desktopFiles.ToLookup(file => file.Extension, StringComparer.InvariantCultureIgnoreCase);

Now use it to get some files into lists. But note that you could also append Count() to just count them, or use all other LINQ methods:

var exeFiles = extensionLookup[".exe"].ToList(); // empty on my desktop
var txtFiles = extensionLookup[".txt"].ToList();
var inkFiles = extensionLookup[".ink"].ToList();
  • Related