65.9K
CodeProject is changing. Read more.
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5 votes)

May 27, 2014

CPOL

2 min read

viewsIcon

67462

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