web-dev-qa-db-ja.com

辞書からn番目の要素を取得するにはどうすればよいですか?

cipher = new Dictionary<char,int>;
cipher.Add( 'a', 324 );
cipher.Add( 'b', 553 );
cipher.Add( 'c', 915 );

2番目の要素を取得する方法は?たとえば、次のようなものが欲しい:

KeyValuePair pair = cipher[1]

ペアに( 'b', 553 )が含まれる場合


リストを使用した協同組合の提案に基づいて、物事は機能しています:

List<KeyValuePair<char, int>> cipher = new List<KeyValuePair<char, int>>();
cipher.Add( new KeyValuePair<char, int>( 'a', 324 ) );
cipher.Add( new KeyValuePair<char, int>( 'b', 553 ) );
cipher.Add( new KeyValuePair<char, int>( 'c', 915 ) );

KeyValuePair<char, int> pair = cipher[ 1 ];

アイテムが追加された順序でリストにとどまることを正しいと仮定すると、提案されたListではなくSortedListを使用できると信じています。

34
Adam Kane

問題は、辞書がソートされていないことです。必要なのは SortedList です。これにより、インデックスだけでなくキーでも値を取得できますが、必要なソートを取得するには、コンストラクターで独自の比較演算子を指定する必要があります。その後、キーと値の順序付きリストにアクセスし、必要に応じてIndexOfKey/IndexOfValueメソッドのさまざまな組み合わせを使用できます。

34
thecoop

このような:

int n = 0;
int nthValue = cipher[cipher.Keys.ToList()[n]];

ページの上部にLinqへの参照も必要になることに注意してください...

using System.Linq;
28
grenade

実際にキーで検索する必要がありますか?そうでない場合は、List<KeyValuePair<char, int>>(さらに良いことに、charとintをカプセル化する型を作成します)。

辞書は本質的にソートされていません-.NETでareにソートされているディクショナリ実装は、挿入順ではなくキーでソートされます。

挿入順序とキーの両方でコレクションにアクセスする必要がある場合、リストと辞書を単一のコレクションタイプにカプセル化することをお勧めします。

または、リストが非常に短い場合は、線形検索を実行するだけでインデックスによる検索を許可します...

17
Jon Skeet

次のようにElementAt()を使用できます。

cipher.ElementAt(index);

Selectオプションよりも優れているのは、この方法では辞書をループする必要がないためです。

ドキュメンテーション

/// <summary>Returns the element at a specified index in a sequence.</summary>
/// <returns>The element at the specified position in the source sequence.</returns>
/// <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1" /> to return an element from.</param>
/// <param name="index">The zero-based index of the element to retrieve.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="source" /> is null.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="index" /> is less than 0 or greater than or equal to the number of elements in <paramref name="source" />.</exception>
6
Sahil Mukheja

辞書の元の仕様に固執するために、私はいくつかのコードを投げて思いついた:

Dictionary<string, string> d = new Dictionary<string, string>();

d.Add("a", "Apple");
d.Add("b", "ball");
d.Add("c", "cat");
d.Add("d", "dog");

int t = 0;
foreach (string s in d.Values)
{
    t++;
    if (t == 2) Console.WriteLine(s);
}

そして、コンソールに2番目の項目(「ボール」)を繰り返し書き込みます。 n番目の要素を取得するメソッド呼び出しにラップすると、おそらく機能します。しかし、これはかなりいです。 @thecoopが示唆しているように、代わりにSortedListを実行できる場合は、その方が良いでしょう。

2
Cyberherbalist

ここで尋ねられたこの質問のduがありました: 辞書のN番目のアイテムを取得する方法? 。すぐに閉じる必要がありますが、ここでの回答には新しいOrderedDictionaryクラスがないことがわかりました。

現在(.NET 4以降)、 OrderedDictionary クラスがあります。これにより、順序付けを提供しながら高速検索が可能になります。 Item(Int32)メソッドは、n番目の要素を返します。

2
vipw

次のLINQクエリを「暗号」Dictionaryに適用できます

        var cipher = new Dictionary<char, int>();
        cipher.Add('a', 324);
        cipher.Add('b', 553);
        cipher.Add('c', 915);

        var nThValue = cipher.Select((Val, Index) => new { Val, Index })
            .Single(viPair => viPair.Index == 1)   //Selecting dictionary item with it's index using index
            .Val                                   //Extracting KeyValuePair from dictionary item
            .Value;                                //Extracting Value from KeyValuePair
0

これは古い質問ですが、役に立ちました。これが私が使用した実装です。 n番目の要素が挿入順序に基づいていることを望みました。

public class IndexedDictionary<TKey, TValue> : IEnumerable<TValue> {
  private List<TValue> list = new List<TValue>();
  private Dictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();

  public TValue this[int index] { get { return list[index]; } }
  public TValue this[TKey key] { get { return dict[key]; } }

  public Dictionary<TKey, TValue>.KeyCollection Keys { get { return dict.Keys; } }

  public int Count { get { return list.Count; } }

  public int IndexOf(TValue item) { return list.IndexOf(item);  }
  public int IndexOfKey(TKey key) { return list.IndexOf(dict[key]); } 

  public void Add(TKey key, TValue value) {
    list.Add(value);
    dict.Add(key, value);
  }

  IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() {
    return list.GetEnumerator();
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return list.GetEnumerator();
  }
}
0
tony722