もこたんブログ@mocuLab(・ω・)

Programming & Designing

C#でLINQを使ったToDictionaryの使い方(ListからDictionaryを作成、DictionaryからDictionaryを作成)

.NET Framework3.5(C#3.5)から使えます。
バージョンが低くて使えない時は、forやforeachで回すしかありません(´・ω・`)

構文

Enumerable.ToDictionary メソッド
https://msdn.microsoft.com/ja-jp/library/system.linq.enumerable.todictionary(v=vs.110).aspx

//        戻り値           メソッド名 
public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
    this IEnumerable<TSource> source,// 拡張メソッド(拡張する型を指定)
    Func<TSource, TKey> keySelector// System.Func<TSource, TKey>型
)

オーバーロードで4つのメソッドがありますがよく使うのは以下の2つだと思います。
・引数が1つ
・引数が2つ

ListからDictionaryを作成

ToDictionaryを使ってListからDictionaryを作ることが簡単にできます。

// 【1-1】引数が1つ
// Valueを指定しない場合
// IdをKey、UserオブジェクトをValueとしたディクショナリを作成
Dictionary<int, User> userDic1 = this.Users.ToDictionary(x => x.Id);

// 【1-2】引数が2つ
// IdをKeyに、NameをValueとしたディクショナリを作成
var userDic2 = this.Users.ToDictionary(x => x.Id, x => x.Name);

DictionaryからDictionaryを作成

ToDictionaryを使えばDictionaryから新しいDictionaryを作ることも簡単にできます。

// 【2-1】引数が1つ
// ValueはuserDic1の<Key, Value>がそのまま入ってくる
// 1-1と同じ使い方。
var userDic3 = userDic1.ToDictionary(x => x.Key);

// 【2-2】引数が2つ
// Keyを多少変更してディクショナリを作り直した例
// 1-2と同じ使い方。
var userDic4 = userDic1.ToDictionary(x => x.Key.ToString().PadLeft(3, '0'), x => x.Value);

サンプルコード全体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ToDictionarySample
{
    public partial class Form1 : Form
    {
        // ユーザーリスト
        public List<User> Users { get; set; }

        // コンストラクタ
        public Form1()
        {
            InitializeComponent();

            this.Users = this.CreateUserList();

            // ■リストからディクショナリを作成

            // 【1-1】引数が1つ
            // Valueを指定しない場合
            // IdをKey、UserオブジェクトをValueとしたディクショナリを作成
            Dictionary<int, User> userDic1 = this.Users.ToDictionary(x => x.Id);

            // 【1-2】引数が2つ
            // IdをKeyに、NameをValueとしたディクショナリを作成
            var userDic2 = this.Users.ToDictionary(x => x.Id, x => x.Name);


            // ■ディクショナリからディクショナリを作成

            // 【2-1】引数が1つ
            // ValueはuserDic1の<Key, Value>がそのまま入ってくる
            // 1-1と同じ使い方。
            var userDic3 = userDic1.ToDictionary(x => x.Key);

            // 【2-2】引数が2つ
            // Keyを多少変更してディクショナリを作り直した例
            // 1-2と同じ使い方。
            var userDic4 = userDic1.ToDictionary(x => x.Key.ToString().PadLeft(3, '0'), x => x.Value);
        }

        #region CreateUserList:検証用のリストを作成
        private List<User> CreateUserList()
        {
            var list = new List<User>();

            for (int i = 1; i < 6; i++)
            {
                var user = new User()
                {
                    Id = i,
                    Name = "名前" + i.ToString(),
                    Birthday = "生年月日" + i.ToString(),
                    Email = "メール" + i.ToString(),
                };
                list.Add(user);
            }

            return list;
        }
        #endregion
    }
}

参考

ToDictionaryのソースコード(Reference Source)
File: System\Linq\Enumerable.cs
Project: ndp\fx\src\Core\System.Core.csproj (System.Core)
http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,97b7f242af9248ab