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