2015-11-12 60 views
5

Ho il seguente codice:Spalato più stringhe in un elenco di oggetti in C#

public class Info 
{ 
    public string Name; 
    public string Num; 
} 

string s1 = "a,b"; 
string s2 = "1,2"; 

IEnumerable<Info> InfoSrc = 
    from name in s1.Split(',') 
    from num in s2.Split(',') 
    select new Info() 
    { 
     Name = name, 
     Num = num 
    }; 

List<Info> listSrc = InfoSrc.ToList(); 

Vorrei che il mio listSrc risultato di contenere due Info elementi i cui Name e Num proprietà sono:

a, 1 
b, 2 

Tuttavia, il codice che mostro sopra risulta in quattro voci:

a, 1 
a, 2 
b, 1 
b, 2 
+0

saranno le spaccature sempre la stessa lunghezza? – Johan

+3

Cerca in 'Enumerable.Zip'. – Kvam

risposta

6

È possibile utilizzare Enumerable.Zip:

IEnumerable<Info> InfoSrc = s1.Split(',') 
    .Zip(s2.Split(','), (name, num) => new Info(){ Name = name, Num = num }); 

Se avete bisogno per associare più di due raccolte a proprietà che è possibile concatenare più Zip insieme a un tipo anonimo che contiene il secondo e il terzo:

IEnumerable<Info> InfoSrc = s1.Split(',') 
    .Zip(s2.Split(',').Zip(s3.Split(','), (second, third) => new { second, third }), 
     (first, x) => new Info { Name = first, Num = x.second, Prop3 = x.third }); 

Ecco una versione spera più leggibile:

var arrays = new List<string[]> { s1.Split(','), s2.Split(','), s3.Split(',') }; 
int minLength = arrays.Min(arr => arr.Length); // to be safe, same behaviour as Zip 
IEnumerable<Info> InfoSrc = Enumerable.Range(0, minLength) 
.Select(i => new Info 
{ 
    Name = arrays[0][i], 
    Num = arrays[1][i], 
    Prop3 = arrays[2][i] 
}); 
+0

Giusto per essere sicuro di capire cosa sta succedendo, in pratica dividi 's1' in una serie di stringhe, quindi' Zip' quella matrice con un'altra matrice creata da 's2'. Questo crea una collezione di elementi in base a qualunque sia il terzo argomento - che in questo caso è il costruttore per l'oggetto 'Info'. Quindi in pratica hai solo una collezione di oggetti "Info"? – sab669

+0

@ sab669: sì, ma non una raccolta. Attualmente è solo una domanda. Se vuoi una collezione devi aggiungere 'ToList' o' ToArray'. 'Enumerable.Zip' enumera due sequenze simultaneamente e restituisce gli oggetti che si trovano allo stesso indice. –

+0

Cosa succede quando ho bisogno di tre stringhe divise di uguale dimensione? Le informazioni ora hanno 3 campi. string s1 = "a, b"; string s2 = "1,2"; string s3 = "G, J"; – user3716892

5

Supponendo che il numero di elementi in ogni elenco è pari, sembra che si sta cercando di Zip insieme ...

s1.Split(',').Zip(s2.Split(','), (name, num) => new Info{Name = name, Num = num}) 
+0

Dovrebbe essere: 'IEnumerable InfoSrc = s1.Split (','). Zip (s2.Split (','), (a, b) => nuove informazioni {Nome = a, Num = b});' –

Problemi correlati