Given a string like "name:Dave"
that I'd like to convert to a Tuple<string,string>
is there a neat way to do this inline using LINQ, rather than first getting the array then parsing it?
I am parsing some config data from my app.config
file like this:
<Data>
<add key="John" value="instrument:guitar"/>
<add key="Paul" value="instrument:bass"/>
<add key="George" value="instrument:guitar"/>
<add key="Ringo" value="instrument:drums"/>
</Data>
Which I want to convert to a Dictionary<string,tuple<string,string>>
(I know this is an odd data structure!)
Starting with some code:
var x = ((ConfigurationManager.GetSection("Data") as Hashtable))
.Cast<System.Collections.DictionaryEntry>()
.ToDictionary(n => n.Key.ToString(), n => something(n.Value.ToString().Split(':')));
I wondered if there's a neat LINQ way to do this in-line rather than write a utility function to get from String.Split's array into a single Tuple?
var source = new Dictionary<string, string>(){ { "John", "instrument:guitar" } };
var tuple = source.Select(x => new { key = x.Key, values = x.Value.Split(':') }).Select(y => new Tuple<string, string>(y.key, y.values[1])).ToList();
Your string is basically an XML
so I would just parse this using XmlDocument
from System.Xml
namespace. Then you can just use GetElementsByTagName
because all values you want to retrieve has the same tag ( <add />
) and then just use it to create a dictionary like such :
string @xml = @"<Data>
<add key=""John"" value=""instrument:guitar""/>
<add key=""Paul"" value=""instrument:bass""/>
<add key=""George"" value=""instrument:guitar""/>
<add key=""Ringo"" value=""instrument:drums""/>
</Data>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(@xml);
var dict = new Dictionary<string, Tuple<string, string>>();
doc.GetElementsByTagName("add")
.OfType<XmlElement>()
.Select(element =>
{
string key = element.Attributes["key"].Value;
string[] value = element.Attributes["value"].Value.Split(':');
dict.Add(key, new Tuple<string, string>(value[0], value[1]));
return dict.Last();
});
return dict;
Which can be shortened into something like this :
XmlDocument doc = new XmlDocument();
doc.LoadXml(@xml);
Dictionary<string, Tuple<string, string>> dict = doc.GetElementsByTagName("add")
.OfType<XmlElement>()
.Select(element => new Tuple<string, string[]>(element.Attributes["key"].Value, element.Attributes["value"].Value.Split(':')))
.ToDictionary(element => element.Item1, element => new Tuple<string, string>(element.Item2[0], element.Item2[1]));
return dict;
Or even shorter :
XmlDocument doc = new XmlDocument();
doc.LoadXml(@xml);
Dictionary<string, Tuple<string, string>> dict = doc.GetElementsByTagName("add")
.OfType<XmlElement>()
.ToDictionary(element => element.Attributes["key"].Value, element => new Tuple<string, string>(element.Attributes["value"].Value.Split(':')[0], element.Attributes["value"].Value.Split(':')[1]));
return dict;
EDIT : ( After question edit )
You can use System.Configuration
library which contains ConfigurationManager
object and do it like such :
ConfigurationManager.AppSettings.AllKeys.ToDictionary(
key =>
key,
key =>
new Tuple<string, string>(
ConfigurationManager.AppSettings[key].Split(':')[0],
ConfigurationManager.AppSettings[key].Split(':')[1]
)
);
But you have to make sure that app.config
contains only the keys you want to process using this method. If you try to process line which looks like <add key="Willy" value="noinstrument" />
that method will break.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With