Doppelte Schlüssel in .NET-Wörterbüchern?

256

Gibt es Wörterbuchklassen in der .NET-Basisklassenbibliothek, mit denen doppelte Schlüssel verwendet werden können? Die einzige Lösung, die ich gefunden habe, besteht darin, beispielsweise eine Klasse wie die folgende zu erstellen:

Dictionary<string, List<object>>

Aber es ist ziemlich irritierend, es tatsächlich zu benutzen. Ich glaube, dass eine MultiMap in Java dies erreicht, aber in .NET kein Analogon finden kann.

Mechanische Schnecke
quelle
3
Wie ist dieser doppelte Schlüssel, es sind doppelte Werte (die Liste), richtig?
Shamim Hafiz
1
@ShamimHafiz, nein, die Werte müssen keine Duplikate sein. Wenn Sie Duplikate { a, 1 }und { a, 2 }in einer Hash-Tabelle speichern müssen, in ader sich der Schlüssel befindet, ist eine Alternative zu haben { a, [1, 2] }.
Nawfal
1
Eigentlich glaube ich, dass hier wirklich eine Sammlung gewünscht wird, in der jeder Schlüssel einem oder mehreren Werten zugeordnet werden kann. Ich denke, dass der Ausdruck "doppelte Schlüssel" dies nicht wirklich vermittelt.
DavidRR
Zum späteren Nachschlagen sollten Sie in Betracht ziehen, 1 Schlüssel beizubehalten, indem Sie nur die Werte hinzufügen, anstatt immer wieder dieselben Schlüssel hinzuzufügen.
Ya Wang
Wenn sowohl Schlüssel als auch Werte Zeichenfolgen sind, gibt es NameValueCollection (die jedem Zeichenfolgenschlüssel mehrere Zeichenfolgenwerte zuordnen kann).
AnorZaken

Antworten:

229

Wenn Sie .NET 3.5 verwenden, verwenden Sie die LookupKlasse.

BEARBEITEN: Sie erstellen in der Regel eine LookupVerwendung Enumerable.ToLookup. Dies setzt voraus, dass Sie es später nicht mehr ändern müssen - aber ich finde das normalerweise gut genug.

Wenn das bei Ihnen nicht funktioniert, gibt es meiner Meinung nach nichts im Framework, das helfen könnte - und die Verwendung des Wörterbuchs ist so gut wie es nur geht :(

Jon Skeet
quelle
Vielen Dank für das Heads-up bei Lookup. Es bietet eine großartige Möglichkeit, Ergebnisse einer Linq-Abfrage zu partitionieren (zu gruppieren), die keine Standardkriterien für die Reihenfolge sind.
Robert Paulson
3
@Josh: Sie verwenden Enumerable.ToLookup, um eine zu erstellen.
Jon Skeet
29
Achtung : Lookupist nicht serialisierbar
SliverNinja - MSFT
1
Wie sollen wir dieser Suche Elemente hinzufügen?
Moldovanu
171

Die List-Klasse eignet sich recht gut für Schlüssel- / Wertsammlungen mit Duplikaten, bei denen Sie die Sammlung durchlaufen möchten. Beispiel:

List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();

// add some values to the collection here

for (int i = 0;  i < list.Count;  i++)
{
    Print(list[i].Key, list[i].Value);
}
John Saunders
quelle
31
Diese Lösung funktioniert funktional, aber die Implementierung von List hat keine Kenntnis des Schlüssels oder Werts und kann die Suche nach Schlüsseln überhaupt nicht optimieren
Spencer Rose
41

Hier ist eine Möglichkeit, dies mit List <KeyValuePair <string, string >> zu tun

public class ListWithDuplicates : List<KeyValuePair<string, string>>
{
    public void Add(string key, string value)
    {
        var element = new KeyValuePair<string, string>(key, value);
        this.Add(element);
    }
}

var list = new ListWithDuplicates();
list.Add("k1", "v1");
list.Add("k1", "v2");
list.Add("k1", "v3");

foreach(var item in list)
{
    string x = string.format("{0}={1}, ", item.Key, item.Value);
}

Ausgänge k1 = v1, k1 = v2, k1 = v3

Hector Correa
quelle
Funktioniert hervorragend in meinem Szenario und ist auch einfach zu bedienen.
user6121177
21

Wenn Sie Zeichenfolgen sowohl als Schlüssel als auch als Werte verwenden, können Sie System.Collections.Specialized.NameValueCollection verwenden , das über die GetValues-Methode (Zeichenfolgenschlüssel) ein Array von Zeichenfolgenwerten zurückgibt.

Matt
quelle
6
NameValueCollection erlaubt nicht mehrere Schlüssel.
Jenny O'Reilly
@ Jenny O'Reilly: Sicher, Sie können doppelte Schlüssel hinzufügen.
isHuman
Genau genommen ist @ JennyO'Reilly korrekt, da in den Anmerkungen auf der verknüpften MSDN-Seite eindeutig angegeben ist: Diese Klasse speichert mehrere Zeichenfolgenwerte unter einem einzigen Schlüssel .
Ronald
Es erlaubt, gibt aber mehrere Werte zurück, ich habe versucht, Index und Schlüssel zu verwenden.
user6121177
18

Ich bin gerade auf die PowerCollections- Bibliothek gestoßen, die unter anderem eine Klasse namens MultiDictionary enthält. Dies schließt diese Art von Funktionalität ordentlich ein.


quelle
14

Sehr wichtiger Hinweis zur Verwendung von Lookup:

Sie können eine Instanz von erstellen, Lookup(TKey, TElement)indem Sie ToLookupein Objekt aufrufen , das implementiert wirdIEnumerable(T)

Es gibt keinen öffentlichen Konstruktor zum Erstellen einer neuen Instanz von a Lookup(TKey, TElement). Darüber hinaus sind Lookup(TKey, TElement)Objekte unveränderlich, dh Sie können keine Elemente oder Schlüssel zu a hinzufügen oder daraus entfernenLookup(TKey, TElement) Objekt nach seiner .

(von MSDN)

Ich würde denken, dass dies ein Show-Stopper für die meisten Anwendungen wäre.

TheSoftwareJedi
quelle
6
Ich kann mir nur sehr wenige Anwendungen vorstellen, bei denen dies ein Show-Stopper wäre. Aber ich finde unveränderliche Objekte großartig.
Joel Mueller
1
@ JoelMueller Ich kann mir viele Fälle vorstellen, in denen dies ein Show Stopper ist. Ein Wörterbuch neu erstellen zu müssen, um ein Element hinzuzufügen, ist keine besonders effiziente Lösung ...
reirab
12

Ich denke, so etwas List<KeyValuePair<object, object>>würde den Job machen.

MADMap
quelle
Wie können Sie etwas in dieser Liste anhand des Schlüssels nachschlagen?
Wayne Bloss
Sie müssen es durchlaufen: aber mir war die LookUp-Klasse von .NET 3.5 nicht bekannt: Vielleicht ist dies für die Suche in ihrem Inhalt nützlicher.
MADMap
2
@wizlib: Die einzige Möglichkeit besteht darin, die Liste zu durchlaufen, was bei weitem nicht so effizient ist wie das Hashing. -1
petr k.
@petrk. Das hängt wirklich davon ab, was Ihre Daten sind. Ich habe diese Implementierung verwendet, weil ich nur sehr wenige eindeutige Schlüssel hatte und nicht den Aufwand für Hash-Kollisionen verursachen wollte. +1
Evan M
9

Wenn Sie> = .NET 4 verwenden, können Sie TupleClass verwenden:

// declaration
var list = new List<Tuple<string, List<object>>>();

// to add an item to the list
var item = Tuple<string, List<object>>("key", new List<object>);
list.Add(item);

// to iterate
foreach(var i in list)
{
    Console.WriteLine(i.Item1.ToString());
}

quelle
Dies sieht nach einer List<KeyValuePair<key, value>>Lösung wie oben aus. Liege ich falsch?
Nathan Goings
6

Es ist einfach genug, eine "eigene" Version eines Wörterbuchs zu erstellen, das "doppelte Schlüssel" -Einträge ermöglicht. Hier ist eine grobe einfache Implementierung. Möglicherweise möchten Sie Unterstützung für die meisten (wenn nicht alle) hinzufügen IDictionary<T>.

public class MultiMap<TKey,TValue>
{
    private readonly Dictionary<TKey,IList<TValue>> storage;

    public MultiMap()
    {
        storage = new Dictionary<TKey,IList<TValue>>();
    }

    public void Add(TKey key, TValue value)
    {
        if (!storage.ContainsKey(key)) storage.Add(key, new List<TValue>());
        storage[key].Add(value);
    }

    public IEnumerable<TKey> Keys
    {
        get { return storage.Keys; }
    }

    public bool ContainsKey(TKey key)
    {
        return storage.ContainsKey(key);
    }

    public IList<TValue> this[TKey key]
    {
        get
        {
            if (!storage.ContainsKey(key))
                throw new KeyNotFoundException(
                    string.Format(
                        "The given key {0} was not found in the collection.", key));
            return storage[key];
        }
    }
}

Ein kurzes Beispiel für die Verwendung:

const string key = "supported_encodings";
var map = new MultiMap<string,Encoding>();
map.Add(key, Encoding.ASCII);
map.Add(key, Encoding.UTF8);
map.Add(key, Encoding.Unicode);

foreach (var existingKey in map.Keys)
{
    var values = map[existingKey];
    Console.WriteLine(string.Join(",", values));
}
ChristopheD
quelle
4

Als Antwort auf die ursprüngliche Frage. So etwas Dictionary<string, List<object>>ist in einer Klasse namens MultiMapThe implementiert Code Project.

Weitere Informationen finden Sie unter dem folgenden Link: http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx

Dan
quelle
3

Die NameValueCollection unterstützt mehrere Zeichenfolgenwerte unter einem Schlüssel (der auch eine Zeichenfolge ist), aber es ist das einzige mir bekannte Beispiel.

Ich neige dazu, Konstrukte ähnlich dem in Ihrem Beispiel zu erstellen, wenn ich auf Situationen stoße, in denen ich diese Art von Funktionalität benötige.

ckramer
quelle
3

Bei Verwendung der List<KeyValuePair<string, object>> Option verwenden, können Sie die Suche mit LINQ durchführen:

List<KeyValuePair<string, object>> myList = new List<KeyValuePair<string, object>>();
//fill it here
var q = from a in myList Where a.Key.Equals("somevalue") Select a.Value
if(q.Count() > 0){ //you've got your value }
Greg
quelle
2
Ja, aber das macht es nicht schneller (immer noch kein Hashing)
Haukman
3

Seit dem neuen C # (ich glaube, es ist von 7.0) können Sie auch so etwas tun:

var duplicatedDictionaryExample = new List<(string Key, string Value)> { ("", "") ... }

und Sie verwenden es als Standardliste, aber mit zwei Werten, die wie gewünscht benannt sind

foreach(var entry in duplicatedDictionaryExample)
{ 
    // do something with the values
    entry.Key;
    entry.Value;
}
Reniasa
quelle
2

Meinen Sie kongruent und kein tatsächliches Duplikat? Andernfalls könnte eine Hashtabelle nicht funktionieren.

Kongruent bedeutet, dass zwei separate Schlüssel auf den entsprechenden Wert gehasht werden können, die Schlüssel jedoch nicht gleich sind.

Beispiel: Angenommen, die Hash-Funktion Ihrer Hashtabelle war nur Hashval = Key Mod 3. Sowohl 1 als auch 4 werden 1 zugeordnet, sind jedoch unterschiedliche Werte. Hier kommt Ihre Idee einer Liste ins Spiel.

Wenn Sie nach 1 suchen müssen, wird dieser Wert auf 1 gehasht, und die Liste wird durchlaufen, bis der Schlüssel = 1 gefunden wird.

Wenn Sie das Einfügen doppelter Schlüssel zulassen würden, könnten Sie nicht unterscheiden, welche Schlüssel welchen Werten zugeordnet sind.

Nicholas Mancuso
quelle
2
Eine Hash-Tabelle verarbeitet bereits Schlüssel, die zufällig mit demselben Wert hashen (dies wird als Kollision bezeichnet). Ich beziehe mich auf eine Situation, in der Sie mehrere Werte genau demselben Schlüssel zuordnen möchten.
2

Die Art, wie ich benutze, ist nur eine

Dictionary<string, List<string>>

Auf diese Weise haben Sie einen einzelnen Schlüssel, der eine Liste von Zeichenfolgen enthält.

Beispiel:

List<string> value = new List<string>();
if (dictionary.Contains(key)) {
     value = dictionary[key];
}
value.Add(newValue);
Stefan Mielke
quelle
Das ist schön und sauber.
Jerry Nixon
Dies ist eine großartige Lösung für meinen Anwendungsfall.
Dub Stylee
1

Ich bin auf der Suche nach derselben Antwort über diesen Beitrag gestolpert und habe keine gefunden. Deshalb habe ich eine Beispiellösung mit einer Liste von Wörterbüchern zusammengestellt und den Operator [] überschrieben, um der Liste ein neues Wörterbuch hinzuzufügen, wenn alle anderen eine haben gegebener Schlüssel (gesetzt), und geben Sie eine Liste von Werten zurück (get).
Es ist hässlich und ineffizient, es wird NUR per Schlüssel abgerufen / gesetzt und es gibt immer eine Liste zurück, aber es funktioniert:

 class DKD {
        List<Dictionary<string, string>> dictionaries;
        public DKD(){
            dictionaries = new List<Dictionary<string, string>>();}
        public object this[string key]{
             get{
                string temp;
                List<string> valueList = new List<string>();
                for (int i = 0; i < dictionaries.Count; i++){
                    dictionaries[i].TryGetValue(key, out temp);
                    if (temp == key){
                        valueList.Add(temp);}}
                return valueList;}
            set{
                for (int i = 0; i < dictionaries.Count; i++){
                    if (dictionaries[i].ContainsKey(key)){
                        continue;}
                    else{
                        dictionaries[i].Add(key,(string) value);
                        return;}}
                dictionaries.Add(new Dictionary<string, string>());
                dictionaries.Last()[key] =(string)value;
            }
        }
    }
Sintrinsic
quelle
1

Ich habe die Antwort von @Hector Correa in eine Erweiterung mit generischen Typen geändert und ihr auch einen benutzerdefinierten TryGetValue hinzugefügt.

  public static class ListWithDuplicateExtensions
  {
    public static void Add<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
    {
      var element = new KeyValuePair<TKey, TValue>(key, value);
      collection.Add(element);
    }

    public static int TryGetValue<TKey, TValue>(this List<KeyValuePair<TKey, TValue>> collection, TKey key, out IEnumerable<TValue> values)
    {
      values = collection.Where(pair => pair.Key.Equals(key)).Select(pair => pair.Value);
      return values.Count();
    }
  }
kjhf
quelle
0

Dies ist ein Weg Weg Concurrent Wörterbuch Ich denke, das wird Ihnen helfen:

public class HashMapDictionary<T1, T2> : System.Collections.IEnumerable
{
    private System.Collections.Concurrent.ConcurrentDictionary<T1, List<T2>> _keyValue = new System.Collections.Concurrent.ConcurrentDictionary<T1, List<T2>>();
    private System.Collections.Concurrent.ConcurrentDictionary<T2, List<T1>> _valueKey = new System.Collections.Concurrent.ConcurrentDictionary<T2, List<T1>>();

    public ICollection<T1> Keys
    {
        get
        {
            return _keyValue.Keys;
        }
    }

    public ICollection<T2> Values
    {
        get
        {
            return _valueKey.Keys;
        }
    }

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

    public bool IsReadOnly
    {
        get
        {
            return false;
        }
    }

    public List<T2> this[T1 index]
    {
        get { return _keyValue[index]; }
        set { _keyValue[index] = value; }
    }

    public List<T1> this[T2 index]
    {
        get { return _valueKey[index]; }
        set { _valueKey[index] = value; }
    }

    public void Add(T1 key, T2 value)
    {
        lock (this)
        {
            if (!_keyValue.TryGetValue(key, out List<T2> result))
                _keyValue.TryAdd(key, new List<T2>() { value });
            else if (!result.Contains(value))
                result.Add(value);

            if (!_valueKey.TryGetValue(value, out List<T1> result2))
                _valueKey.TryAdd(value, new List<T1>() { key });
            else if (!result2.Contains(key))
                result2.Add(key);
        }
    }

    public bool TryGetValues(T1 key, out List<T2> value)
    {
        return _keyValue.TryGetValue(key, out value);
    }

    public bool TryGetKeys(T2 value, out List<T1> key)
    {
        return _valueKey.TryGetValue(value, out key);
    }

    public bool ContainsKey(T1 key)
    {
        return _keyValue.ContainsKey(key);
    }

    public bool ContainsValue(T2 value)
    {
        return _valueKey.ContainsKey(value);
    }

    public void Remove(T1 key)
    {
        lock (this)
        {
            if (_keyValue.TryRemove(key, out List<T2> values))
            {
                foreach (var item in values)
                {
                    var remove2 = _valueKey.TryRemove(item, out List<T1> keys);
                }
            }
        }
    }

    public void Remove(T2 value)
    {
        lock (this)
        {
            if (_valueKey.TryRemove(value, out List<T1> keys))
            {
                foreach (var item in keys)
                {
                    var remove2 = _keyValue.TryRemove(item, out List<T2> values);
                }
            }
        }
    }

    public void Clear()
    {
        _keyValue.Clear();
        _valueKey.Clear();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return _keyValue.GetEnumerator();
    }
}

Beispiele:

public class TestA
{
    public int MyProperty { get; set; }
}

public class TestB
{
    public int MyProperty { get; set; }
}

            HashMapDictionary<TestA, TestB> hashMapDictionary = new HashMapDictionary<TestA, TestB>();

            var a = new TestA() { MyProperty = 9999 };
            var b = new TestB() { MyProperty = 60 };
            var b2 = new TestB() { MyProperty = 5 };
            hashMapDictionary.Add(a, b);
            hashMapDictionary.Add(a, b2);
            hashMapDictionary.TryGetValues(a, out List<TestB> result);
            foreach (var item in result)
            {
                //do something
            }
Ali Yousefi
quelle
0

Ich benutze diese einfache Klasse:

public class ListMap<T,V> : List<KeyValuePair<T, V>>
{
    public void Add(T key, V value) {
        Add(new KeyValuePair<T, V>(key, value));
    }

    public List<V> Get(T key) {
        return FindAll(p => p.Key.Equals(key)).ConvertAll(p=> p.Value);
    }
}

Verwendung:

var fruits = new ListMap<int, string>();
fruits.Add(1, "apple");
fruits.Add(1, "orange");
var c = fruits.Get(1).Count; //c = 2;
John
quelle
0

Sie können Ihren eigenen Wörterbuch-Wrapper erstellen, so etwas wie diesen. Als Bonus unterstützt er den Nullwert als Schlüssel:

/// <summary>
/// Dictionary which supports duplicates and null entries
/// </summary>
/// <typeparam name="TKey">Type of key</typeparam>
/// <typeparam name="TValue">Type of items</typeparam>
public class OpenDictionary<TKey, TValue>
{
    private readonly Lazy<List<TValue>> _nullStorage = new Lazy<List<TValue>>(
        () => new List<TValue>());

    private readonly Dictionary<TKey, List<TValue>> _innerDictionary =
        new Dictionary<TKey, List<TValue>>();

    /// <summary>
    /// Get all entries
    /// </summary>
    public IEnumerable<TValue> Values =>
        _innerDictionary.Values
            .SelectMany(x => x)
            .Concat(_nullStorage.Value);

    /// <summary>
    /// Add an item
    /// </summary>
    public OpenDictionary<TKey, TValue> Add(TKey key, TValue item)
    {
        if (ReferenceEquals(key, null))
            _nullStorage.Value.Add(item);
        else
        {
            if (!_innerDictionary.ContainsKey(key))
                _innerDictionary.Add(key, new List<TValue>());

            _innerDictionary[key].Add(item);
        }

        return this;
    }

    /// <summary>
    /// Remove an entry by key
    /// </summary>
    public OpenDictionary<TKey, TValue> RemoveEntryByKey(TKey key, TValue entry)
    {
        if (ReferenceEquals(key, null))
        {
            int targetIdx = _nullStorage.Value.FindIndex(x => x.Equals(entry));
            if (targetIdx < 0)
                return this;

            _nullStorage.Value.RemoveAt(targetIdx);
        }
        else
        {
            if (!_innerDictionary.ContainsKey(key))
                return this;

            List<TValue> targetChain = _innerDictionary[key];
            if (targetChain.Count == 0)
                return this;

            int targetIdx = targetChain.FindIndex(x => x.Equals(entry));
            if (targetIdx < 0)
                return this;

            targetChain.RemoveAt(targetIdx);
        }

        return this;
    }

    /// <summary>
    /// Remove all entries by key
    /// </summary>
    public OpenDictionary<TKey, TValue> RemoveAllEntriesByKey(TKey key)
    {
        if (ReferenceEquals(key, null))
        {
            if (_nullStorage.IsValueCreated)
                _nullStorage.Value.Clear();
        }       
        else
        {
            if (_innerDictionary.ContainsKey(key))
                _innerDictionary[key].Clear();
        }

        return this;
    }

    /// <summary>
    /// Try get entries by key
    /// </summary>
    public bool TryGetEntries(TKey key, out IReadOnlyList<TValue> entries)
    {
        entries = null;

        if (ReferenceEquals(key, null))
        {
            if (_nullStorage.IsValueCreated)
            {
                entries = _nullStorage.Value;
                return true;
            }
            else return false;
        }
        else
        {
            if (_innerDictionary.ContainsKey(key))
            {
                entries = _innerDictionary[key];
                return true;
            }
            else return false;
        }
    }
}

Das Verwendungsbeispiel:

var dictionary = new OpenDictionary<string, int>();
dictionary.Add("1", 1); 
// The next line won't throw an exception; 
dictionary.Add("1", 2);

dictionary.TryGetEntries("1", out List<int> result); 
// result is { 1, 2 }

dictionary.Add(null, 42);
dictionary.Add(null, 24);
dictionary.TryGetEntries(null, out List<int> result); 
// result is { 42, 24 }
Alexander Tolstikov
quelle
Können Sie erklären, was Ihr Code tut, wie er die Frage beantwortet und welche Beispiele verwendet werden?
Rätselhaftigkeit
@Enigmativity, es macht genau das, was gestellt wurde. Die Frage war, ein Wörterbuch vorzuschlagen, das Duplikate unterstützt. Deshalb habe ich angeboten, einen Wrapper um das .net-Wörterbuch zu erstellen, der diese Funktionalität unterstützt, und als Beispiel einen solchen Wrapper als Bonus erstellt Behandle Null als Schlüssel (auch wenn es sicher eine schlechte Praxis ist). Die Verwendung ist recht einfach: var dictionary = new OpenDictionary<string, int>(); dictionary.Add("1", 1); // The next line won't throw an exception; dictionary.Add("1", 2); dictionary.TryGetEntries("1", out List<int> result); // result is { 1, 2 }
Alexander Tolstikov
Können Sie Ihrer Antwort das Detail hinzufügen?
Rätselhaftigkeit
@ Rätselhaftigkeit, wenn Sie zur ursprünglichen Antwort meinen, dann sicher
Alexander Tolstikov
-1

Sie können eine Methode zum Erstellen eines zusammengesetzten Zeichenfolgenschlüssels überall dort definieren, wo Sie ein Wörterbuch verwenden möchten. Sie müssen diese Methode verwenden, um Ihren Schlüssel zu erstellen, zum Beispiel:

private string keyBuilder(int key1, int key2)
{
    return string.Format("{0}/{1}", key1, key2);
}

zum Benutzen:

myDict.ContainsKey(keyBuilder(key1, key2))
Alireza Esrari
quelle
-3

Doppelte Schlüssel brechen den gesamten Vertrag des Wörterbuchs. In einem Wörterbuch ist jeder Schlüssel eindeutig und einem einzelnen Wert zugeordnet. Wenn Sie ein Objekt mit einer beliebigen Anzahl zusätzlicher Objekte verknüpfen möchten, ist die beste Wahl möglicherweise ein DataSet (im allgemeinen Sprachgebrauch eine Tabelle). Tragen Sie Ihre Schlüssel in eine Spalte und Ihre Werte in die andere ein. Dies ist erheblich langsamer als ein Wörterbuch, aber das ist Ihr Kompromiss, wenn Sie die Fähigkeit verlieren, die Schlüsselobjekte zu hashen.

Ryan
quelle
5
Ist es nicht der Sinn, ein Wörterbuch für den Leistungsgewinn zu verwenden? Die Verwendung eines DataSet scheint nicht besser zu sein als eine List <KeyValuePair <T, U >>.
Doug
-4

Auch das ist möglich:

Dictionary<string, string[]> previousAnswers = null;

Auf diese Weise können wir eindeutige Schlüssel haben. Hoffe das funktioniert bei dir.

Shan
quelle
Das OP fragte nach einem Wörterbuch, das doppelte Schlüssel zulässt.
Skaparate
-10

Sie können dieselben Schlüssel mit unterschiedlichen Groß- und Kleinschreibung hinzufügen, z.

key1
Key1
KEY1
KeY1
kEy1
keY1

Ich weiß, ist eine Scheinantwort, hat aber für mich gearbeitet.

user4459653
quelle
4
Nein, es hat bei dir nicht funktioniert. Wörterbücher ermöglichen eine sehr schnelle Suche - auch als O (1) klassifiziert - nach Schlüsseln. Sie verlieren diese, wenn Sie mehrere Schlüssel mit unterschiedlichen Gehäusen hinzufügen. Wie können Sie sie abrufen? Probieren Sie jede Kombination aus Groß- und Kleinschreibung aus? Unabhängig davon, wie Sie dies tun, entspricht die Leistung nicht der normalen Suche nach einzelnen Wörterbüchern. Dies gilt zusätzlich zu anderen, offensichtlicheren Mängeln wie der Begrenzung der Werte pro Schlüssel, abhängig von der Anzahl der aufräumbaren Zeichen im Schlüssel.
Eugene Beresovsky