如何将 a 转换List <string>
为 a Dictionary<string, int>
?
这应该是从零到 n 的数字。
您可以使用ToDictionary()
从Dictionary
任何IEnumerable
.
var list = new List<string>() { "Foo", "Bar", "Spam" };
// TKey is int, TValue is string
int i = 0;
Dictionary<int,string> dict1 = list.ToDictionary( _ => i++ );
// TKey is string, TValue is int
i = 0;
Dictionary<string,int> dict2 = list.ToDictionary( x => x, _ => i++ );
传递给的 lambdaToDictionary
是keySelector
. 通常您使用它从 中的项目中选择一个属性IEnumerable
作为键,但在这里,我们使用它来提供计数。
编辑:第二个版本使用两个选择器。第一个是关键。通过提供x => x
lambda,我们只是使用来自列表的字符串。第二个选择器是值。在这里,我们提供柜台,i
。
表现
我决定测试我的方法与 pst 方法的性能。
测试代码:
static void Main(string[] args) {
const int N = 1000000;
const int M = 10;
Stopwatch s;
// Generate test list of strings.
var list = Enumerable.Range(0, N).Select(n => n.ToString());
// Just so it's enumerated once before.
var ar = list.ToArray();
// Try Jonathon's method M times.
s = Stopwatch.StartNew();
for (int x = 0; x < M; x++) {
int i = 0;
//var dict1 = list.ToDictionary(_ => i++); // Before question edit
var dict1 = list.ToDictionary(x => x, _ => i++);
}
s.Stop();
Console.WriteLine("Jonathon's i++ method took {0} ms", s.ElapsedMilliseconds);
// Try pst's method M times.
s = Stopwatch.StartNew();
for (int x = 0; x < M; x++) {
var dict2 = list.Select((v, j) => new {v, j}).ToDictionary(p => p.v, p => p.j);
}
s.Stop();
Console.WriteLine("psts' Select() method took {0} ms", s.ElapsedMilliseconds);
Console.ReadLine();
}
输出:
Jonathon's i++ method took 3005 ms
pst's Select() method took 5019 ms
输出(问题编辑后):
Jonathon's i++ method took 3521 ms
pst's Select() method took 5103 ms
总之,通过使用计数器而不是创建中间的匿名类型对象,似乎有大约 40% 的改进。
假设每个项目都映射到键并n
表示源中的索引,则:
var dict = list
.Select((v, i) => new {v, i})
.ToDictionary(p => p.v, p => p.i);
我喜欢这种方法,因为虽然临时匿名类型有点不稳定,但它是一种自包含的无副作用的表达式。
(如果源列表中有任何重复项,这将引发异常。)