8

重複の可能性:
キーと値のペアのリストから辞書に移動する LINQ の方法はありますか?

私は以下のように持っていると仮定しList<string>ます:

var input = new List<string>()
                       {
                           "key1",
                           "value1",
                           "key2",
                           "value2",
                           "key3",
                           "value3",
                           "key4",
                           "value4"
                       };

このリストに基づいて、に変換したいと思いList<KeyValuePair<string, string>>ます。理由は、同じキーを許可するためです。そのため、Dictionary は使用しません。

var output = new List<KeyValuePair<string, string>>()
                       {
                           new KeyValuePair<string, string>("key1", "value1"),
                           new KeyValuePair<string, string>("key2", "value2"),
                           new KeyValuePair<string, string>("key3", "value3"),
                           new KeyValuePair<string, string>("key4", "value4"),
                       };

以下のコードを使用して達成できます。

var keys = new List<string>();
var values = new List<string>();

for (int index = 0; index < input.Count; index++)
{
    if (index % 2 == 0) keys.Add(input[index]);
    else values.Add(input[index]);
}

var result = keys.Zip(values, (key, value) => 
                        new KeyValuePair<string, string>(key, value));

しかし、これは loop を使用する最善の方法ではないと感じていますがfor、組み込みの LINQ を使用してそれを実現する別の方法はありますか?

4

4 に答える 4

10
var output = Enumerable.Range(0, input.Count / 2)
                       .Select(i => Tuple.Create(input[i * 2], input[i * 2 + 1]))
                       .ToList();
于 2012-08-16T06:52:02.080 に答える
6

ここで LINQ を使用することはお勧めしません。実際には理由がなく、LINQ を使用しても何も得られませんが、単純に通常のforループを使用して、反復ごとにカウント変数を 2 ずつ増やします。

var result = new List<KeyValuePair<string, string>>();

for (int index = 1; index < input.Count; index += 2)
{
    result.Add(new KeyValuePair<string, string>(input[index - 1], input[index]));
}

1でインデックスを開始しているので、アイテムの数inputが奇数の場合、つまりinput値の「半分のペア」で終わっている場合に、無効なインデックスにアクセスするための例外に遭遇しないことに注意してください。

于 2012-08-16T06:45:33.740 に答える
4

これを使用できます:

IEnumerable<KeyValuePair<string, string>> list = 
        input.Where((s, i) => i % 2 == 0)
             .Select((s, i) => new KeyValuePair<string, string>(s, input.ElementAt(i * 2 + 1)));
于 2012-08-16T07:09:04.457 に答える
0

LINQ Aggregate() 関数を使用できます (コードは単純なループよりも長くなります)。

var result = 
input.Aggregate(new List<List<string>>(),
                (acc, s) =>
                {
                    if (acc.Count == 0 || acc[acc.Count - 1].Count == 2)
                        acc.Add(new List<string>(2) { s });
                    else
                        acc[acc.Count - 1].Add(s);
                    return acc;
                })
                .Select(x => new KeyValuePair<string, string>(x[0], x[1]))
                .ToList();

NB
これは、最初の入力がジェネリックIEnumerable<string>になり、具体的にはなくても機能しますList<string>

于 2012-08-16T06:52:20.257 に答える