The community is working on translating this tutorial into Bulgarian, but it seems that no one has started the translation process for this article yet. If you can help us, then please click "More info".
Data transformations: the Select() method
So far in this LINQ chapter of the tutorial, we've worked with simple data sources, e.g. a list of integers, strings or simple objects like the User class. We will continue to do so because it's very practical when showing you examples of the various LINQ methods, but keep in mind that with LINQ, the data source might as well be a complex XML document or a huge database.
In this article, we will talk about the Select() method, which allows you to take the data from the data source and shape it into something else. That might be more obviously useful with larger and more complex data sources, like the ones I mention above, but bear with me anyway, while I try to show you how the Select() method works and what you can do with it. As usual, we'll go straight to an example:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqSelect1
{
class Program
{
static void Main(string[] args)
{
List<User> listOfUsers = new List<User>()
{
new User() { Name = "John Doe", Age = 42 },
new User() { Name = "Jane Doe", Age = 34 },
new User() { Name = "Joe Doe", Age = 8 },
new User() { Name = "Another Doe", Age = 15 },
};
List<string> names = listOfUsers.Select(user => user.Name).ToList();
foreach (string name in names)
Console.WriteLine(name);
}
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
}
}
Notice how I can take a list of objects, in this case of the type User, and then use the Select() method to shape this list into a new type of list. In this example, I turn the list of objects into a list of strings containing the names of the users. This is extremely practical in so many situations, where you need your data to look differently, or when you only need a subset of it. Of course, it also works the other way around - you can easily create a list of User objects from a list of names (you will have to manually add their age later though):
List<User> listOfUsers = new List<User>()
{
new User() { Name = "John Doe", Age = 42 },
new User() { Name = "Jane Doe", Age = 34 },
new User() { Name = "Joe Doe", Age = 8 },
new User() { Name = "Another Doe", Age = 15 },
};
List<string> names = listOfUsers.Select(user => user.Name).ToList();
List<User> users = names.Select(name => new User { Name = name }).ToList();
foreach (User user in users)
Console.WriteLine(user.Name);
Notice how I can create new objects with the Select() method - it's an extremely powerful feature, which allows you to do pretty much anything with your data, on the fly! A common usage for this functionality is to make less complex versions of an object, e.g. to return over a web service as JSON or XML. Imagine that you have a User class with a LOT of properties (Birthday, Gender, Mail, Address, Country etc.), but you only want to return a limited set of these properties - that might also make sense, security-wise, to make sure that you don't return common User properties like Username and Password. Here's a simplified example - just imagine a much more complex User class:
using System;
using System.Collections.Generic;
using System.Linq;
namespace LinqSelect2
{
class Program
{
static void Main(string[] args)
{
List<User> listOfUsers = new List<User>()
{
new User() { Name = "John Doe", Mail = "john@doe.com", Age = 42 },
new User() { Name = "Jane Doe", Mail = "jane@doe.com", Age = 34 },
new User() { Name = "Joe Doe", Mail = "joe@doe.com", Age = 8 },
new User() { Name = "Another Doe", Mail = "another@doe.com", Age = 15 },
};
var simpleUsers = listOfUsers.Select(user => new
{
Name = user.Name,
Age = user.Age
});
foreach (var user in simpleUsers)
Console.WriteLine(user.Name);
}
class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
}
}
}
In this example, we use the Select() method to return a list of anonymous types, which contains only a subset of the properties found on the data source. We then do the classical output of these objects to the console, but you should just imagine us returning them to a website or somewhere else, where it's important to keep the result as simple as possible, without revealing any secrets like passwords etc.
As we already discussed, I will mostly be using the method syntax of LINQ in these examples, but of course the operations we perform in this example can be expressed with the LINQ query syntax as well:
// Method syntax
var simpleUsers = listOfUsers.Select(user => new
{
Name = user.Name,
Age = user.Age
});
// Query syntax
var simpleUsersQ = (from user in listOfUsers
select new
{
Name = user.Name,
Age = user.Age
}).ToList();
foreach (var user in simpleUsersQ)
Console.WriteLine(user.Name);
I hope this gives you a clearer idea of which syntax you prefer, but the result is of course the same!
Summary
The Select() method allows you to transform and shape data from your data source into new variants, for instance by selecting only a single property or returning objects which only contains a subset of the properties found on the source object.