2

次の値を含む辞書に含まれるリストがあります

value a
value b
value c
value 1, value 2, value3
value d

私が望む最終結果は

value a
value b
value c
value 1
value 2
value 3
value d

問題は辞書を繰り返し処理していて、ループ中にコレクションを変更しようとしているため、コレクションを変更しようとしても機能しません

string[] ar;
        foreach (var kvp in dict)
        {
            if (kvp.Key == "STAR-016")
            {
                foreach (var v in kvp.Value)
                {
                    if (v.Contains(','))
                    {
                        ar = v.Split(',');
                        foreach (var a in ar)
                        {
                            kvp.Value.Add(a);
                        }
                    }
                }
            }
        }

どうすれば望ましい結果を得ることができますか?

4

5 に答える 5

3

LINQ を使用してみてください。

var list = new List<string>()
{
    "value a",
    "value b",
    "value 1, value 2, value 3",
    "value c"
};

/* THIS IS THE IMPORTANT PART: */
/* Replace list with kvp.Value */
list = list.SelectMany( 
         i => i.Split( ',' ).Select( v => v.Trim() ) 
       ).ToList();

foreach ( var item in list )
    Console.WriteLine( item );

出力:

値 a
値 b
値 1
値 2
値 3
値 c

これをコード内で使用するには:

foreach (var kvp in dict)
{
    if (kvp.Key == "STAR-016")
    {
        var newList = 
            kvp.Value.SelectMany(
                i => i.Split( ',' ).Select( v => v.Trim() )
            );
        kvp.Value.Clear();
        kvp.Value.AddRange(newList);
    }
}

i =>より単純な構文を指摘してくれた@Muduに感謝します

于 2013-02-14T12:56:54.110 に答える
2

を使用して1行でそれを行うことができるはずですSelectMany

dict["STAR-016"] = dict["STAR-016"].SelectMany(s=>s.Split(',')).ToList();

これにより、キーのリストがコンマで文字列を分割するリストに置き換えられます。文字列にコンマが含まれていない場合は、文字列を返すだけです。StringSplitOptions.RemoveEmptyEntries連続するカンマの結果として空の文字列が必要ない場合は、使用を検討することもできます。

于 2013-02-14T13:04:14.913 に答える
2

これは単なる例であり、実際にはキーだけでなくSTAR-016、値 ( List<string>) にコンマが含まれるすべての場所でこれが必要であると仮定します。

Dictionary<string, List<String>> dict = new Dictionary<string, List<String>>();
dict.Add("STAR-016", new List<string>() { 
    "value a", "value b", "value c", "value 1, value 2, value 3", "value d"
});

foreach (var kvp in dict)
{
    for (int i = kvp.Value.Count - 1; i >= 0; i--)
    {
        string str = kvp.Value[i];
        if (str.Contains(','))
        {
            var parts = str.Split(',').Select(p => p.Trim());
            kvp.Value.RemoveAt(i);
            kvp.Value.InsertRange(i, parts);
        }
    }
}

デモ

InsertRangeを増やす新しい文字列を追加するため、複雑さを避けるために最後から最初までループしていCountます。文字列をカンマで置き換えて、新しい文字列 (カンマで区切られた部分ごとに 1 つ) を追加するために
使用しています。順番を守りたいので代わりにRemoveAt使っています。InsertRangeAddRange

結果:

value a
value b
value c
value 1
value 2
value 3
value d
于 2013-02-14T12:53:30.340 に答える