我有格式为 "$0Option one$1$Option two$2$Option three"
(等)的字符串,我想将其转换为字典,其中每个数字对应一个选项。我目前有一个针对此问题的有效解决方案,但由于我正在导入的每个条目(几千个)都会调用此方法,因此我希望它尽可能优化。
public Dictionary<string, int> GetSelValsDictBySelValsString(string selectableValuesString)
{
// Get all numbers in the string.
var correspondingNumbersArray = Regex.Split(selectableValuesString, @"[^\d]+").Where(x => (!String.IsNullOrWhiteSpace(x))).ToArray();
List<int> correspondingNumbers = new List<int>();
int number;
foreach (string s in correspondingNumbersArray)
{
Int32.TryParse(s, out number);
correspondingNumbers.Add(number);
}
selectableValuesString = selectableValuesString.Replace("$", "");
var selectableStringValuesArray = Regex.Split(selectableValuesString, @"[\d]+").Where(x => (!String.IsNullOrWhiteSpace(x))).ToArray();
var selectableValues = new Dictionary<string, int>();
for (int i = 0; i < selectableStringValuesArray.Count(); i++)
{
selectableValues.Add(selectableStringValuesArray.ElementAt(i), correspondingNumbers.ElementAt(i));
}
return selectableValues;
}
最佳答案
在您的代码中引起我注意的第一件事是它对输入字符串进行了三次处理:两次使用 Split()
和一次 Replace()
. Matches()
方法是比 Split()
更好的工具为了这份工作。有了它,您可以一次提取所需的一切。它也使代码更容易阅读。
我注意到的第二件事是所有那些循环和中间对象。您已经在使用 LINQ; 真正使用它,您可以消除所有困惑并提高性能。检查一下:
public static Dictionary<int, string> GetSelectValuesDictionary(string inputString)
{
return Regex.Matches(inputString, @"(?<key>[0-9]+)\$*(?<value>[^$]+)")
.Cast<Match>()
.ToDictionary(
m => int.Parse(m.Groups["key"].Value),
m => m.Groups["value"].Value);
}
注意事项:
-
Cast<Match>()
是必要的,因为MatchCollection
仅将自己宣传为IEnumerable
,我们需要它是一个IEnumerable<Match>
. - 我用了
[0-9]
而不是\d
如果您的值可能包含来自非拉丁文字系统的数字;在 .NET 中,\d
匹配所有这些。 - 静态正则表达式方法,如
Matches()
自动缓存 Regex 对象,但如果此方法将被多次调用(尤其是如果您也使用许多其他正则表达式),您可能想要创建一个静态 Regex 对象。如果性能真的很关键,您可以指定Compiled
选项。 - 我的代码和你的一样,没有尝试处理格式错误的输入。特别是,如果数字太大,我的将抛出异常,而你的只是将其转换为零。这可能与您的真实代码无关,但看到您调用
TryParse()
,我不得不表达我的不安。不检查返回值。 :/ - 您也没有确保您的 key 是唯一的。像@Gabe 一样,我使用数值作为键翻转它,因为它们恰好是唯一的而字符串值不是。我相信这也不是您的真实数据的问题。 ;)
关于c# - 使用正则表达式的字符串到字典(想要优化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5686708/