2017-11-23 15 views
4

は、私は、リストのリストを持っていると仮定します。与えられたリストから新しいリストを作成して、要素が以下の例のようになるようにしたい。要素が新しいリストにあるリストのリストから新しいリストを作成する方法は、代替順序ですか?

入力: -

List<List<int>> l = new List<List<int>>(); 

List<int> a = new List<int>(); 
a.Add(1); 
a.Add(2); 
a.Add(3); 
a.Add(4); 
List<int> b = new List<int>(); 
b.Add(11); 
b.Add(12); 
b.Add(13); 
b.Add(14); 
b.Add(15); 
b.Add(16); 
b.Add(17); 
b.Add(18); 

l.Add(a); 
l.Add(b); 

出力(リスト): -

1 
11 
2 
12 
3 
13 
4 
14 
15 
16 

と出力リストnot contain more than 10要素をする必要があります。

私は現在、foreach inside whileを使用してこれを行っていますが、どうすればいいですか?LINQ

int loopCounter = 0,index=0; 
List<int> o=new List<int>(); 
while(o.Count<10) 
{ 
    foreach(List<int> x in l) 
    { 
     if(o.Count<10) 
      o.Add(x[index]); 
    } 
    index++; 
} 

ありがとうございます。

+0

使用[ 'ジップ()'](https://msdn.microsoft.com/en-us/library/dd267698(V = vs.110).aspxの)と '()' – Dido

+0

ください@ Dido - zipにはリストが1つではなく他のアイテムは含まれません –

+0

LINQを使用する必要がある理由はありますか? –

答えて

3

は、アイテムのインデックスを受け取りSelectManySelectオーバーロードを使用してください。これは、希望の順序を適用するために使用されます。 SelectManyを使用すると、ネストされたコレクションレベルが平坦化されます。

var result = l.SelectMany((nested, index) => 
        nested.Select((item, nestedIndex) => new {index, nestedIndex, item})) 
       .OrderBy(i => i.nestedIndex) 
       .ThenBy(i => i.index) 
       .Select(i => i.item) 
       .Take(10); 
:C#6.0およびそれ以前のプロジェクトに代わりに匿名型を使用している場合

var result = (from c in l.Select((nestedCollection, index) => (nestedCollection, index)) 
       from i in c.nestedCollection.Select((item, index) => (item, index)) 
       orderby i.index, c.index 
       select i.item).Take(10); 

var result = l.SelectMany((nested, index) => 
        nested.Select((item, nestedIndex) => (index, nestedIndex, item))) 
       .OrderBy(i => i.nestedIndex) 
       .ThenBy(i => i.index) 
       .Select(i => i.item) 
       .Take(10); 

またはクエリ構文で:最後に、アイテムの唯一の希望数を取得するためにTakeを適用


Zipだけでは不十分である理由を説明すると、zipはper参加する 属性がインデックスである第一の二の収集、上join操作を形成します。したがって、第1のコレクションに存在するアイテムのみが、第2のコレクションに一致する場合、結果に表示されます。

次のオプションを約left join秒で(存在する場合)が一致して最初のコレクションのすべての項目を返します。これを考えることです。場合にはOPがfull outer joinの機能を探している説明 - 両方のコレクションのすべてのアイテムを取得し、可能な場合に一致します。

+0

@Caius Jard - ここで 'Zip'を使用する際の問題の説明を参照してください –

+0

最初の例ではC#を使用していますか?それはコンパイルされないためです。 'index'はメソッドパラメータ – KernelMode

+0

@ KernelMode - C#7.0と同じ名前です。以前のバージョン(6以下)はその下に記述されています –

2

は、私はあなたがLINQを求めたけど、私は頻繁にLINQがハンマーであるとすぐに、開発者がそれを見つけると、すべての問題は、釘であることを感じています。私はこのような何かを理解するために単純かつ容易だと思うので、私は、ビューの可読性/保守ポイントのために、LINQでこれをやっているだろう/より自己文書化:

List<int> r = new List<int>(10); 
for(int i = 0; i < 10; i++){ 
    if(i < a.Count) 
    r.Add(a[i]); 
    if(i < b.Count) 
    r.Add(b[i]); 
} 

あなたが停止する必要はありませんループは、aとbを総称のみなど8つの項目を持っている初期の場合は、しかし、あなたはループのためのテストを拡張することによってできた

それは多くのことをやっているので、私はまた、この場合は、LINQよりもパフォーマンスのかもしれないと思う

以下

LINQを使用するというあなたの任務が学問的なものであれば(これはLINQを使用する必要がある宿題です)、次に進んでください。しかし、通常の日常的なシステムであれば青梅他の貧しい吸盤は1日維持する必要がありますが、私はこれはこれは、2以上の内部List<List<int>>年代を処理するLINQ

+0

リストの代わりに列挙子を利用できます。入力がIListでない場合は、です。 – qxg

+0

は、2つの内部リストに対してのみ機能します。質問されたリストのリストではありません。 –

+0

これはどこですか? 2つのforループに変換するのは簡単ですが、私の答えは、Linaが適切であると考えていることを、むしろ暗示された問題を解決するよりも適切であると考えることが重要でした。質問のループコードを参照する場合は、この回答が投稿されたときにそのコードが存在しなかったことに注意してください –

0

のための良いアプリケーションであるかどうかを検討するためにあなたを懇願する - それはあなたが呼び出す必要がありyield経由IEnumerable<int>を返します。それをリストにするには.ToList()を入力してください。 Linq.Anyはブレーク基準に使用されます。

すべてのリストをnullにする。あなたの好みにチェックを加えてください。

static IEnumerable<int> FlattenZip (List<List<int>> ienum, int maxLength = int.MaxValue) 
{ 
    int done = 0; 
    int index = 0; 
    int yielded = 0; 

    while (yielded <= maxLength && ienum.Any (list => index < list.Count)) 
    foreach (var l in ienum) 
    { 
     done++; 

     if (index < l.Count) 
     { 
     // this list is big enough, we will take one out 
     yielded++; 
     yield return l[index]; 
     } 

     if (yielded > maxLength) 
     break; // we are done 

     if (done % (ienum.Count) == 0) 
     index += 1; // checked all lists, advancing index 
    } 
} 

public static void Main() 
{ 
    // other testcases to consider: 
    // in total too few elememts 
    // one list empty (but not null) 
    // too many lists (11 for 10 elements) 

    var l1 = new List<int> { 1, 2, 3, 4 }; 
    var l2 = new List<int> { 11, 12, 13, 14, 15, 16 }; 
    var l3 = new List<int> { 21, 22, 23, 24, 25, 26 }; 

    var l = new List<List<int>> { l1, l2, l3 }; 

    var zipped = FlattenZip (l, 10); 

    Console.WriteLine (string.Join (", ", zipped)); 
    Console.ReadLine(); 
} 
関連する問題