2010-11-24 34 views
2

j'ai liste des chaînesShortest façon de créer des instances de classe lorsque les propriétés sont peuplées à partir des données séquentielles

var data = new List<string> {"Name1", "Surname1", "Name2", "Surname2" }; 

et classe qui décrit la personne

class Person 
{ 
    public string Name { get; set; } 
    public string Surname { get; set; } 
} 

Quel est le chemin le plus court pour créer List<Person> peuplé de data liste Le résultat devrait être égal à

var persons = new List<Person> 
{ 
    new Person { Name = "Name1", Surname = "Surname1" }, 
    new Person { Name = "Name2", Surname = "Surname2" } 
}; 

Merci d'avance!

Répondre

6

Si vous pouvez utiliser LINQ, voici une façon:

var persons = Enumerable.Range(0, data.Count/2) 
         .Select(i => new Person 
              { 
              Name = data[2 * i], 
              Surname = data[2 * i + 1] 
              }) 
         .ToList(); 

Vous pouvez voir ce que vaguement équivalent à:

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); 
} 

Voici une autre, moins efficace, la version (fonctionne uniquement sur .NET 4.0) qui utilise le Zipoperator:

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(); 

Vous pouvez également utiliser le Batchoperator de MoreLinq ici:

var persons = data.Batch(2) 
        .Select(pair => new Person 
             { 
             Name = pair.ElementAt(0), 
             Surname = pair.ElementAt(1) 
             }) 
        .ToList(); 
+1

Ceci est une excellente réponse. Je veux voter plus :) – Bryan

2

Si vous voulez faire ce genre de fonction un peu plus générique (peut-être demain personne va prendre 3 valeurs), vous pouvez créer une extension pour renvoyer des morceaux de données:

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(); 
} 

alors dans cette situation nous pourrions faire ce qui suit:

var people = data.GetChunks(2) 
    .Select(s => new Person() { Name = s[0], Surname = s[1] });