Comment puis-je obtenir le nième élément d'un dictionnaire?

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

comment obtenir le 2e élément? Par exemple, je voudrais quelque chose comme:

KeyValuePair pair = cipher[1]

où paire contient ( 'b', 553 )


D'après la suggestion de la coop à l'aide d'une liste, les choses fonctionnent:

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 ];

en supposant que je suis correct que les éléments restent dans la liste dans l'ordre où ils sont ajoutés, je crois que je peux juste utiliser un List par opposition à un SortedList comme le suggère.

32
demandé sur ann 2009-07-23 20:26:50

9 réponses

le problème est Qu'un dictionnaire n'est pas trié. Ce que vous voulez est un SortedList , qui vous permet d'obtenir des valeurs par index aussi bien que par clé, bien que vous puissiez avoir besoin de spécifier votre propre compareur dans le constructeur pour obtenir le tri que vous voulez. Vous pouvez alors accéder à une liste ordonnée des clés et des valeurs, et utiliser diverses combinaisons des méthodes IndexOfKey/IndexOfValue si nécessaire.

35
répondu thecoop 2009-07-23 16:28:31

comme ceci:

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

notez que vous aurez également besoin d'une référence à Linq en haut de votre page...

using System.Linq;
27
répondu grenade 2009-07-23 16:53:42

avez-vous vraiment besoin de regarder vers le haut par la clé? Sinon, utilisez un List<KeyValuePair<char, int>> (ou encore mieux, créez un type pour encapsuler le char et l'int).

Les dictionnaires

ne sont pas triés de façon inhérente - les implémentations de dictionnaires qui sont triées dans .NET sont triées par clé, et non par ordre d'insertion.

si vous avez besoin d'accéder à la collection à la fois par ordre d'insertion et par clé, je vous recommande d'encapsuler une liste et un dictionnaire en un seul type de collection.

alternativement, si la liste va être assez courte, permettre la recherche par index juste en faisant une recherche linéaire...

17
répondu Jon Skeet 2009-07-23 16:49:07

vous pouvez utiliser ElementAt() comme ceci:

cipher.ElementAt(index);

C'est mieux que l'option Select parce que de cette façon vous n'avez pas à boucle à travers le dictionnaire:

documentation

/// <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>
4
répondu Sahil Mukheja 2017-03-02 07:37:14

juste pour vous accrocher à votre spécification d'origine pour un dictionnaire, j'ai slung un peu de code et est venu avec:

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

et il semble écrire le deuxième élément ("boule") à la console de façon répétée. Si vous l'enveloppez dans un appel de méthode pour obtenir l'élément nth, ça marcherait probablement. C'est assez laid. Si vous pouviez faire une liste sorted à la place, comme @thecoop le suggère, vous seriez mieux sans.

2
répondu Cyberherbalist 2009-07-23 16:44:31

il y avait un dupe de cette question posée ici: comment récupérer Nth élément dans le dictionnaire? . Il devrait être fermé bientôt, mais j'ai remarqué que les réponses ici manquent la nouvelle classe de dictionnaires ordonnés.

il y a maintenant (à partir de .NET 4), une classe OrderedDictionary . Cela permet des recherches rapides tout en fournissant la commande. La méthode Item(Int32) renvoie l'élément nth.

2
répondu vipw 2017-05-23 12:31:52

vous pouvez appliquer la requête LINQ suivante sur votre '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's index using index
            .Val                                   //Extracting KeyValuePair from dictionary item
            .Value;                                //Extracting Value from KeyValuePair
0
répondu Olioul Islam Rahi 2015-06-17 06:01:51

C'est une vieille question, mais elle m'a été utile. Voici une implémentation que j'ai utilisée. Je voulais que le nième élément soit basé sur l'ordre d'insertion.

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
répondu tony722 2017-09-12 19:07:30

N'essayez PAS ceci: C'était une idée stupide - désolé les gars!

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

parce que le 2e élément est index 1!

-5
répondu n8wrl 2009-07-23 17:08:22