Reputation: 2022
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 :)
Upvotes: 3
Views: 2081
Reputation: 47
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
}
Upvotes: 0
Reputation: 1151
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)
Upvotes: 1
Reputation: 13022
What you've done so far is good. Then, you have two ways to achieve what you want:
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();
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();
Upvotes: 4