web-dev-qa-db-ja.com

C#でLINQを使用して辞書からSortedDictionaryに変換するにはどうすればよいですか?

Dictionary<string, double>があり、それをSortedDictionary<double, string>に変換したいと思います。 C#3.0でLINQ拡張メソッドを使用してこれを行うにはどうすればよいですか?

編集:マークとジャレッドが答えたとき、元の質問にはない一般的な山かっこ。

28
Guy

editこの回答は編集前でした。更新された問題への回答については、 この返信 を参照してください。

なぜLINQを使用するのですか?このためのコンストラクタがあります:

new SortedDictionary<int, string>(existing);

ToSortedDictionary追加することはできますが、気にしません...

48
Marc Gravell

LINQは必要ありません。 SortedDictionaryには、変換を行うためのコンストラクターがあります。

public SortedDictionary<TKey,TValue> Convert<TKey,TValue>(Dictionary<TKey,TValue> map) {
  return new SortedDictionary<TKey,TValue>(map);
}
8
JaredPar

Dictionary<TKey,TValue>を取得してそれをSortedDictionary<TValue,TKey>に変換するエレガントな方法を求めているようです(Dictionaryの値がSortedDictionaryのキーになっていることに注意してください)。それに対処する答えが見当たらないので、ここに行きます。

次のような拡張メソッドを作成できます。

static class Extensions
{
    public static Dictionary<TValue, TKey> 
         AsInverted<TKey, TValue>(this Dictionary<TKey, TValue> source)
    {
        var inverted = new Dictionary<TValue, TKey>();

        foreach (KeyValuePair<TKey, TValue> key in source)
            inverted.Add(key.Value, key.Key);

        return inverted;
    }
}

そして、アプリケーションコードは次のようになります。

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var dict = new Dictionary<String, Double>();
        dict.Add("four", 4);
        dict.Add("three", 3);
        dict.Add("two", 2);
        dict.Add("five", 5);
        dict.Add("one", 1);

        var sortedDict = new SortedDictionary<Double, String>(dict.AsInverted());
    }
}
5
Andrew Hare

LINQは必要ありませんが、いくつかの気の利いた拡張メソッドが必要です。

public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    return new SortedDictionary<TKey, TValue>(dictionary);
}

public static IDictionary<TKey, TValue> Sort<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    if(comparer == null)
    {
        throw new ArgumentNullException("comparer");
    }

    return new SortedDictionary<TKey, TValue>(dictionary, comparer);
}

使用例:

var dictionary = new Dictionary<int, string>
{
    { 1, "one" },
    { 2, "two" },
    { 0, "zero" }
};

foreach(var pair in dictionary.Sort())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two
1
Bryan Watts

ToDictionaryを使用した反転:

public static IDictionary<TValue, TKey> Invert<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
{
    if(dictionary == null)
    {
        throw new ArgumentNullException("dictionary");
    }

    return dictionary.ToDictionary(pair => pair.Value, pair => pair.Key);
}

使用例:

var dictionary = new Dictionary<string, int>
{
    { "zero", 0 },
    { "one", 1 },
    { "two", 2 }
};

foreach(var pair in dictionary.Invert())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two

反転と並べ替えの例(Sortの定義については他の回答を参照してください):

var dictionary = new Dictionary<string, int>
{
    { "one", 1 },
    { "two", 2 },
    { "zero", 0 }
};

foreach(var pair in dictionary.Invert().Sort())
{
    Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
}

// 0: zero
// 1: one
// 2: two
0
Bryan Watts