Подтвердить что ты не робот

Как я могу получить n-й элемент из Словаря?

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

Как получить второй элемент? Например, мне бы хотелось что-то вроде:

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, как было предложено.

4b9b3361

Ответ 1

Проблема заключается в том, что словарь не отсортирован. Вы хотите SortedList, который позволяет получать значения как по индексу, так и по ключу, хотя вам может потребоваться указать свой собственный компаратор в конструктор, чтобы получить сортировку, которую вы хотите. Затем вы можете получить доступ к упорядоченному списку ключей и значений и использовать различные комбинации методов IndexOfKey/IndexOfValue по мере необходимости.

Ответ 2

вот так:

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

обратите внимание, что вам также понадобится ссылка на Linq в верхней части страницы...

using System.Linq;

Ответ 3

Вам действительно нужно искать ключ? Если нет, используйте List<KeyValuePair<char, int>> (или, еще лучше, создайте тип для инкапсуляции char и int).

Словари не сортируются по своему усмотрению - словарные реализации, которые сортируются в .NET, сортируются по ключу, а не по порядку вставки.

Если вам нужно получить доступ к коллекции с помощью порядка вставки и ключа, я бы рекомендовал инкапсулировать список и словарь в одном типе коллекции.

В качестве альтернативы, если список будет довольно коротким, разрешите поиск по индексу, просто выполнив линейный поиск...

Ответ 4

Чтобы цепляться за оригинальную спецификацию для Словаря, я перебросил код и придумал:

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);
}

и, похоже, повторяется второй элемент ( "мяч" ) на консоли. Если вы завернете его в вызов метода для получения n-го элемента, это, вероятно, сработает. Это довольно уродливо. Если бы вы могли сделать SortedList вместо этого, как подсказывает @thecoop, вам будет лучше.

Ответ 5

Здесь был обманут этот вопрос: Как получить N-й элемент в словаре?. Он должен быть закрыт в ближайшее время, но я заметил, что в ответах здесь отсутствует новый класс OrderedDictionary.

Теперь (с .NET 4), OrderedDictionary класс. Это позволяет быстро выполнять поиск при заказе. Метод Item (Int32) возвращает n-й элемент.

Ответ 6

Вы можете использовать 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>

Ответ 7

Вы можете применить следующий запрос LINQ к вашему 'cipher' 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 index using index
            .Val                                   //Extracting KeyValuePair from dictionary item
            .Value;                                //Extracting Value from KeyValuePair

Ответ 8

Это старый вопрос, но это было полезно для меня. Вот реализация, которую я использовал. Я хотел, чтобы 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();
  }
}

Ответ 9

НЕ пробуйте это: это была глупая идея - извините, ребята!

cipher.Values[1]
cipher.Keys[1]

', потому что элемент 2ND имеет индекс 1!