Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using Linq to create a Dictionary of sub-Lists by grouping from a collection.

0.00/5 (No votes)
27 May 2014 1  
This is really easy - but it's hard to work out for the first time. For example, get a list of files, and group them by the date which is in the 2nd to 10th characters of the name, ignoring extensions. Easy!

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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here