1

これはおそらく単純な質問ですが、答えは私にはわかりません。

辞書に変換しようとしている文字列のコレクションがあります。

コレクション内の各文字列は、正規表現の一致から取得した値のコンマ区切りのリストです。辞書の各エントリのキーをコンマ区切りリストの4番目の要素にし、対応する値をコンマ区切りリストの2番目の要素にします。

ToDictionaryを直接呼び出そうとすると、ある種のループが発生し、現在のBackgroundWorkerスレッドをキックしているように見えます。

var MoveFromItems = matches.Cast<Match>()
                           .SelectMany(m => m.Groups["args"].Captures
                           .Cast<Capture>().Select(c => c.Value));

var dictionary1 = MoveFromItems.ToDictionary(s => s.Split(',')[3], 
                                             s => s.Split(',')[1]);

辞書を手動で作成すると、すべてが正常に機能します。

var MoveFroms = new Dictionary<string, string>();

foreach(string sItem in MoveFromItems) 
{
    string sKey = sItem.Split(',')[3]; 
    string sVal = sItem.Split(',')[1];

    if(!MoveFroms.ContainsKey(sKey))
        MoveFroms[sKey.ToUpper()] = sVal;
}

私はあなたが提供できるかもしれないどんな助けにも感謝します。

4

3 に答える 3

3

問題は、キーに重複がある可能性があります。3つのオプションがあります。

最初のエントリを保持 します(これは、現在foreachループで実行していることです)

キーにはエントリが1つだけあり、最初のエントリが表示されます。つまり、Dictionary:を持つことができます。

var first = MoveFromItems.Select(x => x.Split(','))
                         .GroupBy(x => x[3])
                         .ToDictionary(x => x.Key, x => x.First()[1]);

すべてのエントリをグループ化して保持

キーには複数のエントリがあり(各キーはを返します)、:の代わりにEnumerableを使用します。LookupDictionary

var lookup = MoveFromItems.Select(x => x.Split(','))
                          .ToLookup(x => x[3], x => x[1]);

すべてのエントリをフラット化して保持

キーのようなものはなく、単にエントリのフラット化されたリストです。

var flat = MoveFromItems.Select(x => x.Split(','))
                        .Select(x => new KeyValuePair<string,string>(x[3], x[1]));

代わりに、ここ()でタプルを使用することもできますTuple.Create(x[3], x[1]);


注:これらの場合、キーを大文字にするか小文字にするかを決定する必要があります。私はまだそれに関連することは何もしていません。キーを上位として保存する場合は、上記のすべてでに変更x[3]してください。x[3].ToUpper()

于 2012-05-17T01:40:32.387 に答える
1

これにより、各アイテムが分割され、4番目の分割値からキーが選択され、2番目の分割値から値がすべてディクショナリに選択されます。

var dictionary = MoveFromItems.Select(s => s.Split(','))
                              .ToDictionary(split => split[3],
                                            split => split[1]);

異なるインデックスを使用するためだけに、文字列を2回分割しても意味がありません。

これは、分割結果をローカル変数に保存し、それを使用してインデックス3と1にアクセスするのと同じです。

ただし、実際にキーが再発するかどうかわからない場合は、間違いなく、実装した単純なループを選択します。

ループに小さなバグがありますが、次のようになります。

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

foreach(string sItem in MoveFromItems) 
{
    string sKey = sItem.Split(',')[3]; 
    string sVal = sItem.Split(',')[1];

    // sKey might not exist as a key
    if (!MoveFroms.ContainsKey(sKey))
    //if (!MoveFroms.ContainsKey(sKey.ToUpper()))
    {
        // but sKey.ToUpper() might exist!
        MoveFroms[sKey.ToUpper()] = sVal;     
    }
}

ContainsKey(sKey.ToUpper())キーをすべて大文字にしたい場合は、自分の状態でも実行する必要があります。

于 2012-05-17T01:27:12.047 に答える
1

これにより、Split各文字列がキーとして4番目のアイテム(3番目のインデックス)を作成し、値として2番目のアイテム(1番目のインデックス)を作成します。MoveFromItems','

var dict = MoveFromItems.Select(x => x.Split(','))
                         .ToLookup(x => x[3], x => x[1]);
于 2012-05-17T01:27:08.433 に答える