2017-12-08 23 views
1

私はDictionary<string,string>を別のDictionaryの複合キーとして使用しています。文字列[] []内の文字列[]内のすべての順列から辞書コンポジットキーを作成

また、複合キーとして使用する必要な文字列を含むstring[]配列もあります。例えば

//Dictionary that will use composite key 
Dictionary<Dictionary<string, string>, decimal> lookUpDictionary = new Dictionary<Dictionary<string, string>, decimal>(); 

//The composite key dictionary 
Dictionary<string, string> compositeKey = new Dictionary<string, string>(); 

//Array containing strings 
string[] array1 = { "aa", "bb", "cc" }; 
string[] array2 = { "xx", "yy", "zz" }; 

//A container for the array of individual units 
string[][] arrayOfArrays = {array1,array2}; 

私は、各アレイ内の文字列のすべての組み合わせのペアのうち、複合キーを作成したいと思います。

aa aa 
aa bb 
aa cc 
bb aa 
bb bb 
bb cc 
cc aa 
cc bb 
cc cc 

と二番目の配列のために:たとえば、私のような... compositeKeyは、配列1 string[]のすべての順列とDictionary<string, string>のthats埋めるしたい

xx xx 
xx yy 
xx zz 
yy xx 
yy yy 
yy zz 
zz xx 
zz yy 
zz zz 

を私が持っているものしようとすると、正しい順序で必要な順列を得るために働くように見えるこのネストループアルゴリズムです。

Dictionary<string, string> compositeKey = new Dictionary<string, string>(); 

string[] array1 = { "aa", "bb", "cc" }; 
string[] array2 = { "xx", "yy", "zz" }; 

string[][] arrayOfArrays = {array1,array2}; 


//for every string[] in the arrayofarrays[][] 
foreach(string[] array in arrayOfArrays) 
{ 
    //for every string in each of those string[] arrays in the arrayOfArrays[][] 
    foreach(string word in array) 
    { 
     //get every combination including itself 
     foreach(string wordsPair in array) 
     { 
      string[] permutation = { word, wordsPair }; 
      Console.WriteLine(permutation[0] + permutation[1]); 
      try 
      { 
       //compositeKey.Add(permutation[0], permutation[1]); 
       //string value = compositeKey[permutation[0]]; 
       //Console.WriteLine(value); 
      } 
      catch 
      { 

      } 


     } 

    } 
} 

try catchブロック内のセクションで問題が発生しています。 compositeKeyを正しく作成できないようです。これはネストされたループのためですか、またはdictionarysを完全に間違って使用していますか?

編集:誤った方法で辞書を使用しようとしているようです。ここで使用すべきデータ型の型に関する提案はありますか?

アドバイスありがとうございます。

+1

辞書には、ユニークなキーを持っている必要があります。同じキーが複数回使用されています。だから辞書は辞書> – jdweng

+0

@jdwengでなければなりませんリストは私のコンポジットキーに本当に欲しくないですか?私はDictionary 、decimal>にコンポジットキー(Dictionary )の形で2つの文字列を入れ、そこから10進数を取得したいと思います。 – Jamin

+0

@jdweng私は、私が想定していない方法で辞書を使用しようとしています。あなたが提案する別のデータ型か、Dictionary >メソッドの使用例がありますか? – Jamin

答えて

2

すべての可能な組み合わせを作成するとき、あなたはデカルトを探しているが、それ自体で、あなたのケースで、配列に参加します。

string test = string.Join(Environment.NewLine, arrayOfArrays 
    .Select(line => $"[{string.Join(", ", line)}]")); 

    Console.WriteLine(test); 

アウトカム:あなたstring[]を使用してはならないこと

[aa, aa] 
[aa, bb] 
[aa, cc] 
[bb, aa] 
[bb, bb] 
[bb, cc] 
[cc, aa] 
[cc, bb] 
[cc, cc] 

してください、予告、それは簡単にの助けLINQの

string[] array1 = { "aa", "bb", "cc" }; 
    //string[] array2 = { "xx", "yy", "zz" }; 

    string[][] arrayOfArrays = array1 
    .SelectMany(left => array1, (left, right) => new string[] { left, right }) 
    .ToArray(); 

テストで実装することができます配列のimplementatからのキーを辞書に入れますイオンがないオーバーライドGetHashCodeEquals行います

// Don't do this! Do not use string[] as a key... 
    Dictionary<string[], string> demo = new Dictionary<string[], string>() { 
    {new string[] {"a", "b"}, "c"}, 
    }; 

    string[] key = new string[] {"a", "b"};  

    // ... And that's the reason why: 
    if (!demo.ContainsKey(key)) 
    Console.WriteLine("Oops!"); 

を代わりにTuple<string, string>を選択することもできます。

string[] array1 = { "aa", "bb", "cc" }; 

    Dictionary<Tuple<string, string>, string> dictionary = array1 
    .SelectMany(left => array1, (left, right) => new Tuple<string, string>(left, right)) 
    .ToDictionary(item => item, 
        item => "value for " + string.Join(" & ", item.Item1, item.Item2)); 

    Console.WriteLine(string.Join(Environment.NewLine, dictionary)); 

がアウトカム:

[(aa, aa), value for aa & aa] 
[(aa, bb), value for aa & bb] 
[(aa, cc), value for aa & cc] 
[(bb, aa), value for bb & aa] 
[(bb, bb), value for bb & bb] 
[(bb, cc), value for bb & cc] 
[(cc, aa), value for cc & aa] 
[(cc, bb), value for cc & bb] 
[(cc, cc), value for cc & cc] 
+0

うわー、それは素晴らしいです。ありがとう。 – Jamin

関連する問題