Flattening Two Dimensional Arrays

Well hello everyone, Happy New Year!  I know I’m a few weeks late.  As part of my New Years resolution I’ve promised myself to write at least one blog entry a month.  This is a programming blog and I have yet to write about anything that has to do with programming as of yet.  I’ve also aimed to change that in the New Year as well.  As I didn’t know what to blog about I thought I would start off on something pretty simple.

Today’s blog will be about flattening two dimensional arrays in C# using the Select Many LINQ statement.  I know what you’re thinking.  “I can read all about this in the MSDN help in the web site”.  Yes, you can.  I’ve read it too in preparation for this blog entry.  I’ve also read it before and not REALLY understood it because I’ve not had a need to use it in the REAL world.  It wasn’t until then that I figured out that I didn’t fully understand it.

Enumerable.SelectMany<TSource, TResult> Method (IEnumerable<TSource>, Func<TSource, IEnumerable<TResult>>)

Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

Basically it will flatten a two dimensional array into a single array.  I was recently presented with the challenge that needed this to solve my problem.  I was pulling out items from the database and then grouping them by an id.  When I did this I found myself in a quandary.  I now had a two dimensional array that I was unable to work with.

Creating Two Dimensional Arrays in Real Life

Here is an example of the database structure of the ArtWorks table.

ItemId

ArtistId

Name

Description

43

2

Yellow Sweater

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

44

2

Rio

Fusce eget risus odio, eu tincidunt ligula.

45

2

Garbage

Donec sollicitudin arcu eu risus gravida ut auctor orci convallis.

56

4

Diana

Aliquam eu urna ornare magna rutrum commodo.

72

4

Beagle

Nulla pulvinar risus eget velit blandit a tincidunt libero sodales.

When I pull the information from the database and then grouped by ArtistId, I would have two records.

var artwork = artWorks.GroupBy(aw => aw.ArtistId);

The above method pulls the data out of the ArtWorks table and then groups the records by the ArtistId property.  The GroupBy method returns an IQueryable<IGrouping<TKey, TSource>>.  In our case the return value is an IQueryable<IGrouping<Int32, ArtWork>>.  The output would look something like this:

5IEnumerable<IGrouping<Int32,ArtWork>> (2 items)4

Key=

2

 

5IGrouping<Int32,ArtWork> (3 items)4

ItemId

ArtistId

Name

Description

43

2

Yellow Sweater

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

44

2

Rio

Fusce eget risus odio, eu tincidunt ligula.

45

2

Garbage

Donec sollicitudin arcu eu risus gravida ut auctor orci convallis.

Key=

4

 

5IGrouping<Int32,ArtWork> (2 items)4

ItemId

ArtistId

Name

Description

56

4

Diana

Aliquam eu urna ornare magna rutrum commodo.

72

4

Beagle

Nulla pulvinar risus eget velit blandit a tincidunt libero sodales.

Please notice the shape of the data.  The key that we have selected, ArtistId, now contains an IEnumerable<ArtWork> as its value.  For ArtistId 2, there are three pieces of artwork.  For ArtistId 4, there are two pieces listed.

Hey wait a minute; I thought this blog was about flattening two dimensional arrays, all you’ve done is create one!

You are correct, but I had to get you to this point so that you could learn how to flatten out these values.  I feel that if is important to learn how to get to that point, so that it will be easier to understand the shape of the data you are trying to flatten.

Flattening the Data

Now we need to pull out all of the ItemIds into a single flat array to pull some metadata, or some other action.  I could flatten the array manually without using any LINQ methods.

       var itemIds = new List<int>();

       foreach(var grp in artwork)

       {

              var ids = new List<int>();

              foreach(var item in grp)

              {

                     itemIds.Add(item.ItemId);

              }

       }

This will produce the following list of integers.

5List<Int32> (5 items)4

43

44

45

56

72

Now let’s try the same thing again using the SelectMany and Select LINQ statements.

var LINQItemIds = artwork.SelectMany(art => art.Select(m => m.ItemId));

5IEnumerable<Int32> (5 items)4

43

44

45

56

72

As you can see both produce the same data, but one does it in a single line of code.

Why is this important?  Simple, the fewer lines of code that you write the less chance you have of making an error.  What did he say?  OK, OK, let me say that with the caveat of the fewer lines of code that you write that follow S.O.L.I.D. principles and leave you with easy to read maintainable code will produce fewer bugs.

I hope that in my first programming blog that I’ve shed a little light on the subject of flattening two dimensional arrays in a way that you found useful.  If you have a suggestion, drop me a line.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s