41

public class Person
{
    public string NickName{ get; set; }
    public string Name{ get; set; }
}

var pl = new List<Person>;

var q = from p in pl
        where p.Name.First() == 'A'
        orderby p.NickName
        select new KeyValuePair<String, String>(p.NickName, p.Name);

var d1 = q.ToList(); // Gives List<KeyValuePair<string, string>>
var d2 = q.ToDictionary(); // Does not compile

Dictionary<文字列、文字列>を取得するには?

4

6 に答える 6

42

の値を指定する必要があります。Dictionary

var d2 = q.ToDictionary(p => p.NickName, p => p.Name);
于 2012-12-19T09:52:49.567 に答える
12

ディクショナリには複数の等しいキーを含めることはできないため、そうでないことを確認 (または認識) する必要があります。GroupByそれを確実にするために使用できます:

Dictionary<string, string> dict = pl
        .Where(p => p.Name.First() == 'A')
        .GroupBy(p => p.NickName)
        .ToDictionary(g => g.Key, g => g.First().Name); 
于 2012-12-19T09:57:43.090 に答える
8

編集

IEnumerable<KeyValuePair<TKey, TValue>>から暗黙的に取得する必要があると本当に感じている場合Dictionaryは、この拡張機能を追加できます。

public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToDictionary(p => p.Key, p => p.Value);
}

次にToDictionary()、任意のIEnumerable<KeyValuePair<TKey, TValue>>.

編集2

重複が予想される場合は、ToLookup()拡張機能も作成できます。

public static ILookup<TKey, TValue> ToLookup<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source)
{
    return source.ToLookup(p => p.Key, p => p.Value);
}

または、本当に結果を破棄したい場合は、 のオーバーロードを追加できますToDictionary

public static IDictionary<TKey, ToValue> ToDictionary<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> source,
    Func<<IEnumerable<TValue>, TValue> selector)
{
    return source
        .Lookup(p => p.Key, p => p.Value);
        .ToDictionary(l => l.Key, l => selector(l));
}

「最初の」項目以外のすべてを任意に破棄する場合 (それが なしで意味することは何OrderByですか) 、この拡張機能を次のように使用できます。

pairs.ToDictionary(v => v.First()); 

全体として、ほとんどのコードを削除して、

var q = from p in pl
        where p.Name.First() == 'A';
var d = q.ToDictionary(p => p.NickName, p => p.Name);

重複する可能性がある場合は

var d = q.ToLookup(p => p.NickName, p => p.Name);

ただし、これは を返しILookup<TKey, TElement>、そのItemインデクサーは を返すIEnumerable<TElement>ため、データを破棄しないことに注意してください。

于 2012-12-19T09:57:35.737 に答える
5

ニックネームをキー、名前を値として以下を試してください

var d2 = q.ToDictionary (p => p.NickName, p=>p.Name);

ただし、辞書では重複が許可されていないため、上記では同じニックネームを持つ重複レコードに対してエラーがスローされることに注意してください。おそらく、Dictionary に似ているが重複を許可する Lookup を使用したいと思うでしょう。

var d2 = q.ToLookup (p => p.NickName, p=>p.Name);
于 2012-12-19T09:54:24.023 に答える
0

でタグ付けされていることに気付きましたが、文字通り、昨日vb.netでこれを行う方法を理解しようとしていた、VB でもこれを行う方法を共有したいと思いました。

Public Class Person
    Property NickName As String
    Property Name As String
End Class

Sub Main()
    Dim p1 As New List(Of Person)

    '*** Fill the list here ***

    Dim q = (From p In p1
             Where p.Name.First = "A"
             Select p.NickName, p.Name).ToDictionary(
                                           Function(k) k.NickName, 
                                           Function(v) v.Name)
End Sub
于 2012-12-19T14:23:41.647 に答える