如何将List <string>转换为Dictionary <string,int =“”>?</string,> </string>

时间:2012-11-29 05:39:35

标签: c# c#-4.0

如何将List <string>转换为Dictionary<string, int>

这应该是从零到n的数字。

2 个答案:

答案 0 :(得分:5)

您可以使用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++ );

传递给ToDictionary的lambda是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%的改进。

答案 1 :(得分:4)

假设每个项目都映射到密钥,并且n代表源中的索引,那么:

var dict = list
    .Select((v, i) => new {v, i})
    .ToDictionary(p => p.v, p => p.i);

我喜欢这种方法,因为虽然临时匿名类型有点不稳定,但它是一种独立的副作用自由表达。

(如果源列表中有任何重复项,则会抛出异常。)