我认为那些对基本字符串操作,循环和字典有轻微把握的人可以解决如何从字符串填充字典,如下所示:
黑色:#00000 |绿色:#008000 | (其中“黑色”是键,“#000000”是值)
但在你看来,最优雅的做法是什么?我可以使用哪种最有效/更简洁的编码来实现它?到目前为止,我有:
public static Dictionary<String, String> ThemeColors
{
get
{
Dictionary<String, String> themeColors = new Dictionary<string, string>();
foreach (String colorAndCode in GetSettingByName("ThemeColors").ToString().Split('|'))
{
themeColors.Add(colorAndCode.Split(':').First(), colorAndCode.Split(':').Last());
}
return themeColors;
}
}
GetSettingByName(“ThemeColours”)返回上面的字符串(以粗体显示)。
它的功能很明显,一切正常,但我想确保我现在开始思考这个并制定最好的做事方式,而不仅仅是让它发挥作用。
我可以在Dictionary循环上使用yield吗?例如??
答案 0 :(得分:8)
public static Dictionary<String, String> ThemeColors
{
get
{
return GetSettingByName("ThemeColors").ToString().Split('|').ToDictionary(colorAndCode => colorAndCode.Split(':').First(), colorAndCode => colorAndCode.Split(':').Last());
}
}
正如评论中建议的更优雅的方式
public static Dictionary<String, String> ThemeColors2
{
get
{
return GetSettingByName("ThemeColors").ToString().Split('|').Select(x => x.Split(new[] { ':' }, 2)).ToDictionary(x => x[0], x => x[1]);
}
}
答案 1 :(得分:4)
我实际上最喜欢你的方法的一个轻微变体:
public static Dictionary<String, String> ThemeColors
{
get
{
Dictionary<String, String> themeColors = new Dictionary<string, string>();
foreach (String colorAndCode in GetSettingByName("ThemeColors").ToString().Split('|'))
{
var parts = colorAndCode.Split(':');
themeColors.Add(parts[0], parts[1]);
}
return themeColors;
}
}
唯一的区别是第二个Split()
只执行一次,而直接索引则不是First()
和Last()
。
现在ToDictionary()
很有意义,在更广泛的查询中包含某些内容是有道理的,我当然不会认为它错了,但这并不像你的方法特别冗长或任何东西。
但是我喜欢改变容忍重复的方法很容易(使用dict[parts[0]] = parts[1]
并且它会覆盖重复而不是抛出),但是也很容易改为抛出Black:#00000:#010101
通过测试parts
的大小。
在另一个方向,如果你需要尽可能快地解析一个庞大的字符串,那么就把优雅抛出窗口并用一些东西替换它,然后通过|
字符串进行扫描。而不是使用Split()
。
与此同时,上述内容在简洁和精确之间形成了良好的中间地带。
答案 2 :(得分:3)
这是一个使用foreach的替代方案。 @Haris Hasan和@vcsjones的答案本身就很优雅。我展示这个的原因是我将这个逻辑封装在一个静态StringHelper类中,然后这个方法可以用作string的扩展。
上述任何一个答案的代码都可以纳入此方法。
调用示例:
var str = "Black:#00000|Green:#008000|";
Dictionary<string, string> dict = str.NameValuePairsToDictionary(":", "|");
/// <summary>
/// convert a string that consists of Name/Value Pairs to a Dictionary.
/// Name and Value are separated by a given name/value separator
/// Pairs are separated by a given pair separator token.
/// example:
/// Black:#00000|Green:#008000
/// </summary>
/// <param name="nvParis">string of name value pairs</param>
/// <param name="nvSeparator">string that separates the name and value in a name value pair</param>
/// <param name="pairSeparator">string that separates the name/value pairs from each other</param>
/// <returns>Dictionary of Name value pairs as string,string</returns>
public static class StringHelper
{
public static Dictionary<string, string> NameValuePairsToDictionary(this string nvPairs, string nvSeparator, string pairSeparator)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
// default - "\n\r"
// split name value pairs by separator
string[] items = nvPairs.Split(pairSeparator.ToCharArray());
// for each split item, split the name/value pair by
// pair separator to add a dictionary item
foreach (string item in items)
{
string[] keyVal = item.Split(nvSeparator.ToCharArray());
if (keyVal.Length > 1)
dict.Add(keyVal[0], keyVal[1]);
}
return dict;
}
}
答案 3 :(得分:1)
object settings = "Black:#00000|Green:#008000|";
var themeColors = (from setting in ((string)settings).Split('|')
where setting != ""
select setting.Split(new[]{':'}, 2))
.ToDictionary(a => a[0], a => a[1]);