J'ai un dictionnaire auquel j'accède normalement avec une clé, j'ai donc besoin de lectures rapides d'accès aléatoire. Cependant pour une fonction je dois traiter chaque article dans le dictionnaire où la commande est importante. Il semble fonctionner correctement dans les tests. Est-il acceptable de dépendre de l'ordre des éléments dans un dictionnaire?Lorsque je parcourrai un dictionnaire (structure de données générique .NET), est-ce que ce sera dans le même ordre que je les ai ajoutés?
Répondre
Non. Si vous avez besoin de garder une commande, vous devriez également avoir une liste d'articles. Vous pouvez encapsuler toutes les opérations dont vous avez besoin dans votre propre classe de collection, ce qui mettrait à jour à la fois le dictionnaire et la liste en même temps.
Il est regrettable que .NET ne dispose pas d'un dictionnaire qui le supporte lui-même - c'est une requête relativement courante - Java le fait, comme LinkedHashMap.
Non. Il est préférable d'utiliser un SortedDictionary si vous souhaitez conserver vos clés dans l'ordre.
Editer: Soit cela, ou ajouter vos clés à une liste liée si vous voulez garder une trace de la commande que vous avez ajouté les éléments.
tpower
, Dictionary
et SortedDictionary
sont très similaires en ce qu'ils contiennent tous deux une collection d'objets, accessibles par une clé. Où ils diffèrent est dans la façon dont ils sont construits à l'interne.
Dictionary
est plus rapide pour l'insertion autant que je sache, alors que SortedDictionary
est construit au-dessus d'un algorithme de recherche d'arbre binaire et est plus rapide pour la lecture.
Dans les deux cas cependant, l'ordre interne est maintenu par l'ordre des clés. Rien ne garantit que la commande que vous parcourez dans l'ensemble de la collection sera la même que celle que vous avez insérée dans vos articles.
Dans ce cas, vous devrez peut-être stocker à la fois une liste et un dictionnaire pour vos différentes exigences.
Pour le dictionnaire, l'ordre n'est simplement pas défini (et peut changer à mesure que la taille change); il ne dépend pas de la clé * order * - mais dépend clairement des valeurs de clé, de leurs hashes, du nombre de buckets, etc. –
Re performance; SortedDictionary est * plus lent * à lire; O (log n) pour SortedList <,> et SortedDictionary <,>, vs O (1) pour le dictionnaire <,>. Parmi les deux triés, le SortedList <,> prend moins de mémoire et est plus rapide à insérer * données pré-triées * (pour les données non triées, SortedDictionary <,> est une insertion plus rapide). –
(plus lent à lire en fonction de l'accès par clé, source: MSDN) –
La documentation indique clairement que « Aux fins de l'énumération, chaque élément dans le dictionnaire est traité comme une structure KeyValuePair < (de < (TKey, TValue>)>) représentant une valeur et sa clé. L'ordre dans lequel les articles sont retournés est indéfini. " mais je ne suis pas convaincu.
Dans tous les tests que j'ai effectués, les articles sont toujours classés par insertion.
Je trouve cette étrange parce que j'ai aussi testé HashMap et LinkedHashMap (en Java) et l'ordre dans la HashMap n'est pas correct comme prévu mais, comme Jon Skeet dit, l'ordre est LinkedHashMap. Est-ce que quelqu'un peut pointer un test d'échec avec le dictionnaire?
Voici le code que j'utilise pour tester:
IDictionary<string, int> dic = new Dictionary<string, int>(10);
Console.WriteLine("Adding ...");
for (int i = 0; i < 1000000; i++)
{
Guid guid = Guid.NewGuid();
dic.Add(guid.ToString(), i);
}
Console.WriteLine("Testing ...");
bool first = true;
int lastItem = 0;
foreach (var item in dic.Values)
{
if (first)
{
first = false;
}
else
{
if (lastItem != item - 1)
{
Console.WriteLine("Test Failed !");
break;
}
}
lastItem = item;
}
Console.WriteLine("Done.");
Hmmmm ... très intéressant! Même si je force beaucoup de suppressions, il reste assez stable. Pourtant, si les docs disent "indéfini", ce ne serait pas une bonne idée de les ignorer ... même si elle est stable aujourd'hui, ce n'est pas forcément le cas. –
Vous ne pouvez certainement pas compter sur ce test pour prouver que le dictionnaire restera trié pour toujours. Il se peut que d'autres changements dans la mémoire ou même le temps entre les insertions/suppressions puissent affecter l'ordre, et la seule façon de savoir avec certitude est de découvrir comment le dictionnaire fonctionne dans les coulisses, ce qui n'est pas une tâche simple. . – gillyb
Vous ne peut certainement pas compter sur Dictionnaire <> retour des résultats dans l'ordre que vous les avez ajoutés - tout comme les états de documentation. Lors du test, le dictionnaire <> semble toujours énumérer les KeyValuePairs <> dans le même ordre que celui où ils ont été ajoutés. Cependant, l'implémentation Mono du dictionnaire <> ne fonctionne pas.Mono suit la documentation lors de l'implémentation du comportement, et je suppose qu'ils ont vu cette partie de la documentation et ensuite implémenté d'une manière qui n'a pas maintenu l'ordre.
Une autre option consiste à utiliser OrderedDictionary, pour maintenir l'ordre.
en utilisant un dictionnaire trié n'a pas de corrélation directe à itérer les éléments dans l'ordre où ils ont été ajoutés (voir sujet) –