What is Projection?

I think there’s great benefit in not only knowing how to design your code to use common patterns but also to be able to speak about them clearly and concisely to others. If I mention that the problem sounds like it could be solved using the Strategy Pattern, somebody who knows what I’m talking about shouldn’t need much more of an explanation than that. Knowing certain terms in code will help with communication. Obviously, the better your team is at communicating, the more successful you’re going to be.

Very Simple Projection

I’ve seen the following code all over the place. It’s very common to turn one collection into another or loop through and capture certain properties of the items you’re enumerating. How often have you seen this code:

public IList<string> GetNames(IEnumerable<Person> people)
{
IList<string> names = new List<string>();
foreach (var person in people)
{
names.Add(person.Name);
}
return names;
}

This is simple projection, but languages are seemingly giving you better ways to achieve this same thing. I’ll get to that later.

Different types of projection

I see three basic types of projection. There are variations of these same ideas, but for the most part these cover the bulk.

  • Selection: Imagine you have a collection of customers and you want only the email addresses, this is where selection projection would be used. This isn’t always a one-to-one relationship, your customers may have more than one email address (if you allow it) and you’ll end up with more items in the projected collection than the starting collection.

  • Creational: This is the type of projection that returns new values from an existing collection. Below, you’ll see two concrete examples in C#.

  • Transformation: Given a list of numbers, you want those numbers squared. This is similar to creational, because you’ll be getting a new item, but it shouldn’t modify the elements in the original collection.

Projection with LINQ in C#

An example that lends itself well to the concept of projection is the following:

My user interface allows strings to come into my application. I want to transform these strings into tags like any blog post, video or photo might have assigned to it. I don’t want my tag service class to have to deal with strings, I want to give it a collection of Tag objects. How do I do this?

With LINQ, this creational projection was very simple:

public void SaveTags(IEnumerable<string> tagNames)
{
var tags = tagNames.Select(name => new Tag(name));
tagService.SaveOrUpdateTags(tags);
}

Another great use of creational projection are some of the usages I’ve seen with SelectListItems in the ASP.NET MVC space. Given a list of objects, create a list of HTML drop down items for a select list.

K. Scott Allen has a good write up entitled Drop-down Lists and ASP.NET MVC on this very thing. There are also many good examples over on the MSDN Visual C# Developer Center.

Your Thoughts on Projection…

I see this pattern often enough but I don’t hear the term “projection” nearly as often. Is there a more common name to this that I’m not hearing or are people just not referring to it by this name?

Related:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chris Missal

Oh hey, I'm a Senior Consultant for Headspring in Austin, TX. I've been working in software professionally since 2006 and I really, really love it. I'm mostly in the Microsoft world, but enjoy building computer things of all sorts (to be vague). When I'm not slinging code, I'm probably out and about slinging discs, bowling balls, or good beer with great friends.
This entry was posted in Communication, LINQ, Reading Code. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.withaguide.com David Mitchell

    Is projection a term used outside of .net? Hadn’t heard it before.

    Never heard it called projection. In Smalltalk-80 the names were methods in the collection library:
    select:
    collect:
    inject:into:
    Most Smalltalker’s I know use the idiom names from Kent Beclk’s Smalltalk Best Practice Patterns book and he named each of these by the method names, above.

    Ruby borrowed those terms but also included aliases from Python:
    find:
    map:
    reduce:

    I know LISP also had these idioms (where Smalltalk-80 got them). But my lisp-foo fails me now. reduce: or inject:into: was a foldr or right fold.

    Of the above, I don’t think reduce or inject-into meets your definition of projection because you get a single element back, not a collection.

    Or, is projection something different?69

  • http://www.lostechies.com/members/chrismissal/default.aspx Chris Missal

    David,

    That’s part of the question. Is this a term that is used with .Net and LINQ only? That’s the only place I had heard it used so far. I would say overall it best equals Map in other languages. If memory serves me correctly, it’s called ‘Map’ in F# and JavaScript as well…

  • http://jonfuller.codingtomusic.com Jon Fuller

    I have heard projection used usually in the regards to a database (NHibernate guys use that word alot, and I’ve heard one of the MongoDB devs use that word too). However, in most conversations I have around this topic, the word map is usually thrown around.

  • J Smith

    I heard project, and projection used in the early releases of Data Access Guidance used in conjunction with the first release of the Web Service Software Factory where I saw the Repository used. I’m not sure PnP coined the term, but that’s where I remember seeing first. Then when 2.0 gained tranction at our shop and then later LINQ-to-SQL, I heard the term used in DAL construction conversations, but not at any other level.

    I still think projection works, it was a term I thought of like this. Given a group of things that need to be reproduced in a different way much the way your described Select, Create, Transform examples, they could be projected based on the need.

    In the DAG example, we transformed and (re)created entities going into and out of the DAL. Much of the projection code live there. The other MVC example mentioned gets it up in the presentation layer, which could also be useful, as long as the developer doesn’t sprinkle extension methods everywhere.

    I have seen this pattern, but sometimes during code reviews they are used as convenience and in some cases are much more like a giant utility method. I don’t think that’s where you were going, but the example you gave could sit nicely inside an extension class to be (re)used by base class entities.

  • http://www.tavaresstudios.com Chris Tavares

    Projection is the term from the relational database world. Map is the same term in a functional / mathematical context. They’re basically the same thing.

    Linq uses projection because a lot of the Linq design was built around dealing with various data sources in a uniform way, so using a db-centric vocabulary fits.

  • http://www.lostechies.com/members/chrismissal/default.aspx Chris Missal

    It seems like Projection is more from the database world.. Huh, suppose Microsoft is using it with their LINQ operators because of their obsession with data? ;)

    I have heard of, and used the term Map before. I think I’ll just split duties with this since it appears to be a bit more ubiquitous. Maybe it won’t matter, but I still think there’s benefit in using these terms to convey a bit more meaning in concise terms.

    Thanks for the feedback!

  • http://blog.markrendle.net/ Mark Rendle

    It drives me nuts that the Map function in LINQ is called Select; then the .NET team complain that people think LINQ is just for databases.

  • Stuart Wheelwright

    I believe ‘Projection’ is a term taken from relational algebra which is the maths that database and Linq are built upon:

    see: http://en.wikipedia.org/wiki/Relational_algebra for more info

  • http://www.lostechies.com/members/chrismissal/default.aspx Chris Missal

    Mark,
    I’m with you on the naming. I don’t think they did a good job with what they named some of those extension methods. Seeing many of those for the first time was confusing to me. Select/Single/First seemed weird to me at first.

  • Nathan Evans

    On your list you have Selection. This can be done using the SelectMany() in LINQ.