Question

I have a string of data:

Key1=Value1,Key2=Value2,KeyN=ValueN

I'm trying to split the string into

List<KeyValuePair<string, string>>

I can easily do this:

List<string[]> values = item.Split( ',' ).Select( p => p.Split( '=' ) ).ToList();

but I just can't figure out the way to get that into the List of KeyValuePair's. The closest I've gotten so far is:

List<KeyValuePair<string, string>> values = item.Split( ',' )
.Select( p => new KeyValuePair<string, string>(){ p.Split( '=' ) } ).ToList();

But that's still a bit off :(

I know I can easily do it with a loop but I'd really like to get it working in Linq as practice makes perfect. I've seen quite a few examples already of similar questions like this one, but I can't seem to join the dots between those questions and mine so please forgive me if I've accidentally posted a duplicate.

Any help would really be appreciated, thanks :)

Was it helpful?

Solution

What you've done so far is good. Then, you have two ways to achieve what you want:

Create a method ToKeyValuePair

public static KeyValuePair<string, string> ToKeyValuePair(string[] array)
{
    if (array.Length != 2)
        throw new ArgumentException("The array must contain exactly 2 elements.");

    return new KeyValuePair<string, string>(array[0], array[1]);
}

var values = (item.Split( ',' )
                  .Select( p => ToKeyValuePair(p.Split( '=' ))))
                  .ToList();

Use the LINQ query syntax

If I convert the above line into query syntax:

var values = (from p in item.Split( ',' )
              select ToKeyValuePair(p.Split( '=' )))
             .ToList();

Not much has changed.

But, thanks to this new syntax, it is quite easy to remove the usage of ToKeyValuePair(...) thanks to the let clause:

var values = (from p in item.Split( ',' )
              let splittedP = p.Split( '=' )  // Declares a variable
              select new KeyValuePair<string, string>(splittedP[0], splittedP[1]))
             .ToList();

Of course, the last line can be written with Extention methods syntax (ie with .Select(p=>...)), but is hard to read:

var values = (item.Split(',')
                  .Select(p => new { p, splittedP = p.Split('=') })
                  .Select(p => new KeyValuePair<string, string>(p.splittedP[0], p.splittedP[1])))
                  .ToList();

OTHER TIPS

I know this is an old question but I stumbled across it on google. I solved the problem using the accepted answer but a shortened it a little. You don't need the new { p, splittedP = p.Split('=') } part, just p.Split('=')

var values = data.Split(',').Select(p=>p.Split('='))
              .Select(s => new KeyValuePair<string, string>(s[0], s[1]))
              .ToList();

You could also do something like this if your keys are unique:

var values = data.Split(',').Select(p => p.Split('='))
              .ToDictionary(k => k[0], v => v[1]);

Which is much shorter and basically gets you a list with with O(1) access.

(This is with .NET 4.5)

use above code. must trim the key.

public static string GetUserInfo(this X509Certificate2 x509,X509Oid oid)
{
      try
      {
           var kvs = x509.Subject.Split(',').Select(x => new KeyValuePair<string, string>(x.Split('=')[0].Trim(), x.Split('=')[1].Trim())).ToList();

           string value = kvs.FirstOrDefault(A => A.Key == oid.ToString()).Value;
           return value;
       }
       catch (Exception)
       {   
       }
       return "";
}

Add an enum file.

public enum X509Oid
{
        O,
        E,
        L,
        C,
        S,
        G,
        SN,
        CN,
        Street
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top