cipher = new Dictionary<char,int>;
cipher.Add( 'a', 324 );
cipher.Add( 'b', 553 );
cipher.Add( 'c', 915 );
Как получить 2-й элемент? Например, я хотел бы получить что-то вроде:
KeyValuePair pair = cipher[1]
Где пара содержит ( 'b', 553 )
.
В соответствии с предложением coop'а использовать List, все работает:
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
, как было предложено.
Проблема в том, что словарь не сортируется. Вам нужен SortedList, который позволяет получать значения по индексу, а также по ключу, хотя для получения нужной сортировки вам, возможно, придется указать в конструкторе собственный компаратор. Затем вы можете получить доступ к упорядоченному списку ключей и значений и использовать различные комбинации методов IndexOfKey/IndexOfValue по мере необходимости.
вот так:
int n = 0;
int nthValue = cipher[cipher.Keys.ToList()[n]];
обратите внимание, что вам также понадобится ссылка на Linq в верхней части вашей страницы...
using System.Linq;
Вы на самом деле нужно искать ключ? Если нет, то использовать список<KeyValuePair<типа char, и int>>
(или еще лучше, создать тип инкапсуляции чар и Инт).
Словари не'т отсортированный по сути - словарь реализаций, которые являются отсортированы по .Чистый сортируются по ключу, а не по порядку вставки.
Если вам нужно получить доступ к коллекции как заказать и ключевые вставки, Я'd рекомендую инкапсуляция список и словарь в одном типа коллекции.
Кроме того, если список будет достаточно коротким, позволяют поиск по индексу, просто делать линейный поиск...
Вы можете использовать ElementAt ()`, как это:
cipher.ElementAt(index);
Его лучше, чем выберите опцию
потому что таким образом вы не'т придется перебрать словарь:
/// <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>
Был Боян этот вопрос здесь: https://stackoverflow.com/questions/6384528/how-to-retrieve-nth-item-in-dictionary/6384552. Он должен быть закрыт в ближайшее время, но я заметил, что ответы здесь не хватает нового класса OrderedDictionary.
Там сейчас (по состоянию на .Сеть 4), в OrderedDictionary класс. Это позволяет быстро поиска при предоставлении заказа. Пункт(int32) метод возвращает N-й элемент.
Просто, чтобы ухватиться за ваш первоначальный образец для Словаря, я набросал немного кода и придумал:
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, вам было бы лучше.
Можно применить следующий запрос LINQ на ваш 'шифр' словарь
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
Это старый вопрос, но это было полезно для меня. Здесь'с реализация, что я использовал. Я хотел энный элемент должен быть основан на порядке вставки.
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();
}
}