Reputation: 7750
I have list of strings
var data = new List<string> {"Name1", "Surname1", "Name2", "Surname2" };
and class that describes Person
class Person
{
public string Name { get; set; }
public string Surname { get; set; }
}
What is the shortest way to create List<Person>
populated from data
list
The result should be equal to
var persons = new List<Person>
{
new Person { Name = "Name1", Surname = "Surname1" },
new Person { Name = "Name2", Surname = "Surname2" }
};
Thank you in advance!
Upvotes: 2
Views: 509
Reputation: 20471
If you wanted to make this kind of function a little more generic (maybe tomorrow Person will take 3 values), you could create an extension method to return chunks of data:
public static List<List<T>> GetChunks<T>(this IList<T> list, int chunkSize)
{
return Enumerable
.Range(0, list.Count / chunkSize)
.Select(i => Enumerable
.Range(0, chunkSize)
.Select(j => list[i * chunkSize + j])
.ToList())
.ToList();
}
then in this situation we could do the following:
var people = data.GetChunks(2)
.Select(s => new Person() { Name = s[0], Surname = s[1] });
Upvotes: 2
Reputation: 113452
If you can use LINQ, here's one way:
var persons = Enumerable.Range(0, data.Count / 2)
.Select(i => new Person
{
Name = data[2 * i],
Surname = data[2 * i + 1]
})
.ToList();
You can view this as loosely equivalent to:
var persons = new List<Person>();
for(int i = 0; i < data.Count / 2 ; i++)
{
var person = new Person
{
Name = data[2 * i],
Surname = data[2 * i + 1]
};
persons.Add(person);
}
Here's another, less efficient, version (works only on .NET 4.0) that uses the Zip
operator:
var names = data.Where((s, i) => i % 2 == 0);
var surnames = data.Where((s, i) => i % 2 == 1);
var persons = names.Zip(surnames,
(name, surname) => new Person
{
Name = name,
Surname = surname
})
.ToList();
You could also use the Batch
operator from MoreLinq here:
var persons = data.Batch(2)
.Select(pair => new Person
{
Name = pair.ElementAt(0),
Surname = pair.ElementAt(1)
})
.ToList();
Upvotes: 6