2017-09-18 3 views
0

私は少し複雑な辞書を持っています。C#:この特定の2D/3Dディクショナリを初期化して入力する最も簡単な方法は?

それは私がそれを使用したいときに、私はこのような何か2つの列挙型を保持している辞書&一覧>

<
Dictionary<BiomeType, Dictionary<LocationType, List<string>>> myDictionary; 

です:私が追加しようとすると

//Add "myString" to the List<string> 
myDictionary[BiomeType.Jungle][LocationType.City1].Add("myString")); 

を"myString"をmyListに渡すと、明らかなエラー&が発生する: "KeyNotFoundException:指定されたキーが辞書に存在しない"

キーがない場合は、自動的にディクショナリを追加する方法はありますか?私は多くのBiomeTypes &さらにLocationTypeを持っています。各リストを作成してから、それぞれのロケーションタイプの辞書を作成し、それをすべてのBiomeTypeに追加する必要があるのはPITAです。これらのすべては、この複雑な辞書を初期化するためだけに機能します。これを行う簡単な方法はありませんか?

私は辞書にオブジェクトを格納するために、gamedevのためにこれを使用していますので、私は

おそらく
BiomeType playerCurrentBiomeType; 
LocationType playerCurrentLocationType; 
LoadLevel(myDictionary[playerCurrentBiomeType][playerCurrentLocationType]); 

//ex. myDictionary[BiomeType.Jungle][LocationType.CapitalCity] 
//ex. myDictionary[BiomeType.Desert][LocationType.CapitalCity] 
//ex. myDictionary[BiomeType.Desert][LocationType.City3] 
+0

明らかに、誰もが単純にすべてを行ごとに追加するだけで、通常の方法で簡単に初期化できることを暗示しています。しかし、私が言及したように、それはリストの後にリストを作成する巨大なPITAであり、その後、それらのリストによって占められた新しい辞書を作成し、最後にこれらの辞書をもう1つの辞書に追加する。簡単な方法があるかどうかを確認するだけです。 – Carter81

+0

私は、すべてを保持するために1つの辞書を使用することはできません。代わりに、各バイオームのための単一の辞書、またはそれらの行に沿ったものを作成することができます。しかし、BiomeType/LocationTypeを使用するだけで、単一のコンテナ内のすべてのオブジェクトを単純に取得するという考えが好きでした。よりシンプルに見えました。 – Carter81

+0

C#は 'Dictionary'について何も知らないので、簡単な方法はありません。これを行うにはコードを書く必要があります。 –

答えて

0

は完全にこの多次元辞書を取り込むために動作します。

Dictionary<BiomeType, Dictionary<LocationType, List<string>>> myDictionary = new Dictionary<BiomeType, Dictionary<LocationType, List<string>>>(); //No thanks to troll users like Peter. Fuck you Pete. 
    foreach (BiomeType biomeType in System.Enum.GetValues(typeof(BiomeType))) 
    { 
     Dictionary<LocationType, List<string>> newLocDict = new Dictionary<LocationType, List<string>>(); //No thanks to troll users like Peter. Fuck you Pete. 

     foreach (LocationType locType in System.Enum.GetValues(typeof(LocationType))) 
     { 
      List<string> newList = new List<string>(); 
      newLocDict.Add(locType, newList); //Add the final bit here & voila! Finished! No thanks to troll users like Peter. Fuck you Pete. 
     } 

     myDictionary.Add(biomeType, newLocDict); 
    } 

Robynのソリューションは、すべての列挙型の値をコンテナに完全に取り込みたくない場合は同じ方法で動作します。

1

ような何かをすることによってそれらにアクセスすることができ、あなたはこれを試すことができます。

Dictionary<BiomeType, Dictionary<LocationType, List<string>>> myDictionary = new Dictionary<BiomeType, Dictionary<LocationType, List<string>>>(); 

BiomeType playerCurrentBiomeType; 
LocationType playerCurrentLocationType; 

if(!myDictionary.ContainsKey(playerCurrentBiomeType)) 
{ 
    myDictionary.Add(playerCurrentBiomeType, new Dictionary<LocationType , List<string>>{{playerCurrentLocationType, new List<string>()}}); 
} 

myDictionary[playerCurrentBiomeType][playerCurrentLocationType].Add("bla"); 
1

あなたは

以下のクラスは、一般的に辞書のように動作し、尋ねられたことを行い、他の変更を隠すタイプです(このクラスは、存在しない項目をインデクサーに尋ねるたびに作成される空の項目が表示されます。

public class SmellyDictionary<T1, T2>: IDictionary<T1, T2>, ICollection where T2 : ICollection, new() 
{ 
    private readonly IDictionary<T1, T2> _dict = new Dictionary<T1, T2>(); 

    public T2 this[T1 key] 
    { 
     get 
     { 
      T2 value; 
      if (!_dict.TryGetValue(key, out value)) 
       _dict[key] = value = new T2(); // This stinks! 
      return value; 
     } 
     set { _dict[key] = value; } 
    } 

    public bool Contains(KeyValuePair<T1, T2> item) 
    { 
     return _dict.Contains(item); 
    } 

    public bool ContainsKey(T1 key) 
    { 
     return _dict.ContainsKey(key) && _dict[key].Count > 0; // This hides the smell 
    } 

    public int Count { get { return _dict.Count(kvp => kvp.Value.Count > 0); } } // This hides the smell 

    public void Add(T1 key, T2 value) 
    { 
     T2 currentValue; 
     if (_dict.TryGetValue(key, out currentValue) && currentValue.Count > 0) 
      throw new ArgumentException("A non empty element with the same key already exists in the SmellyDictionary"); 
     _dict[key] = value; 
    } 

    public void Add(KeyValuePair<T1, T2> item) 
    { 
     Add(item.Key, item.Value); 
    } 

    public bool Remove(T1 key) 
    { 
     return _dict.Remove(key); 
    } 

    public bool Remove(KeyValuePair<T1, T2> item) 
    { 
     return _dict.Remove(item); 
    } 

    public bool TryGetValue(T1 key, out T2 value) 
    { 
     return _dict.TryGetValue(key, out value); 
    } 

    public ICollection<T1> Keys { get { return _dict.Keys; } } 
    public ICollection<T2> Values { get { return _dict.Values; } } 
    public object SyncRoot { get { return ((ICollection)_dict).SyncRoot; } } 
    public bool IsSynchronized { get { return ((ICollection)_dict).IsSynchronized; } } 

    public IEnumerator<KeyValuePair<T1, T2>> GetEnumerator() 
    { 
     return _dict.GetEnumerator(); 
    } 

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

    public void Clear() 
    { 
     _dict.Clear(); 
    } 

    public void CopyTo(Array array, int index) 
    { 
     _dict.CopyTo((KeyValuePair<T1, T2>[])array, index); 
    } 

    public void CopyTo(KeyValuePair<T1, T2>[] array, int arrayIndex) 
    { 
     _dict.CopyTo(array, arrayIndex); 
    } 

    public bool IsReadOnly { get { return _dict.IsReadOnly; } } 
} 
1

ここでは、少し賢明な選択肢があります。このメソッドを呼び出すだけで、辞書に文字列を追加できます。単に新しい値を追加し、すべての可能な列挙型&をループ

private void AddCityToDictionary(Dictionary<BiomeType, Dictionary<LocationType, List<string>>> myDictionary, BiomeType biome, LocationType location, string city) 
    { 
     Dictionary<LocationType, List<string>> locationDictionary; 
     if (!myDictionary.TryGetValue(biome, out locationDictionary)) 
      locationDictionary = myDictionary[biome] = new Dictionary<LocationType, List<string>>(); 
     List<string> cityList; 
     if (!locationDictionary.TryGetValue(location, out cityList)) 
      cityList = locationDictionary[location] = new List<string>(); 
     cityList.Add(city); 
    } 
関連する問題