Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split multiple strings into a list of objects in C#

I have the following code:

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

I would like my listSrc result to contain two Info items whose Name and Num properties are:

a, 1
b, 2

However, the code I show above results in four items:

a, 1
a, 2
b, 1
b, 2
like image 356
user3716892 Avatar asked Nov 12 '15 15:11

user3716892


People also ask

How do you split a string and add to list?

The split() method splits a string into a list. You can specify the separator, default separator is any whitespace. Note: When maxsplit is specified, the list will contain the specified number of elements plus one.

How can I convert comma separated string into a list string C#?

To convert a delimited string to a sequence of strings in C#, you can use the String. Split() method. Since the Split() method returns a string array, you can convert it into a List using the ToList() method.

How do you split a character in a string in C#?

In C#, Split() is a string class method. The Split() method returns an array of strings generated by splitting of original string separated by the delimiters passed as a parameter in Split() method. The delimiters can be a character or an array of characters or an array of strings.


2 Answers

You can use Enumerable.Zip:

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

If you need to map more than two collections to properties you could chain multiple Zip together with an anonymous type holding the second and third:

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

Here is a hopefully more readable version:

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]
 });
like image 63
Tim Schmelter Avatar answered Oct 14 '22 22:10

Tim Schmelter


Assuming that the number of items in each list is equal, it looks like you're trying to Zip them together...

s1.Split(',').Zip(s2.Split(','), (name, num) => new Info{Name = name, Num = num})
like image 5
spender Avatar answered Oct 14 '22 22:10

spender