Introduction
I had a problem where I was passed an array of paths to files, and I had to group them together according to a portion of the file name. Let's say they were log files from a number of subsystems, and so they all had different prefixes, then the date in ISO format, then some more text (sometimes) and an extension which was often - but not always - ".log". Needless to say, the list isn't sorted by anything particularly useful...
D:\Logs\AB20140525Dx3.log
D:\Logs\AB20140526ELM.log
X:\updates\XH20140526.txt
D:\Logs\AB20140527Dx3.log
X:\updates\Logs\AB20140527ELM.log
C:\XH20140527.txt
Now, group them together so that you can process all of todays files as one group, yesterdays as a different one, and so forth.
20140525 D:\Logs\AB20140525Dx3.log
20140526 D:\Logs\AB20140526ELM.log, X:\updates\XH20140526.txt
20140527 D:\Logs\AB20140527Dx3.log, X:\updates\Logs\AB20140527ELM.log, C:\XH20140527.txt
It should be simple, with Linq - and it is.
Background
The problem is not working out what to do - that's obvious, a Dictionary<string, List<string>>
is perfect - but finding out exactly how to do it took me far, far too long - hence this little tip.
Using the code
Dictionary<string, List<string>> groups = rawFiles.GroupBy(r => GetDateFromPath(r)).ToDictionary(g => g.Key, g => g.ToList());
You need a "working" method to extract the info you want, but in this case that is trivial:
private string GetDateFromPath(string path)
{
return Path.GetFileNameWithoutExtension(path).Substring(2, 8);
}
A brief description of how to use the article or code. The class names, the methods and properties, any tricks or tips.
So, how does it work?
Dictionary<string, List<string>> groups
Somewhere to put the results
rawFiles.GroupBy(r => GetDateFromPath(r))
Group the input paths by just the info we are interested in - the date info becomes the dictionary Key, and the Group contains the paths that have the same date info.
.ToDictionary(g => g.Key, g => g.ToList());
Ah! Magic! :laugh: ToDictionary is what caused me grief, because the MSDN documentation is very poor, and the examples I found on the internet didn't quite work - probably because they were for slightly different purposes and I misinterpreted what they actually did.
ToDictionary takes two parameters, and converts the group (or other enumerable) into the values.
The first parameter is a key (which we obviously get from the Groups key we created earlier) and teh section is so damn obvious I can't believe it took me that long to work out...just convert the Group to a List...simple, isn't it? Once you figure out that both parameters need a lambda, and that one of them needs ToList anyway... :doh:
History
Original version