title: How to split multi-level list of tuples into multi-level lists of values using LINQ?
body: <p>I have a <code>List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt;</code> variable and I want to split it to three <code>List&lt;List&lt;int&gt;&gt;</code>s. I already can enumerate the list three time like this:  </p>
  
  <pre><code>List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples = ...
  List&lt;List&lt;int&gt;&gt; a = tuples.Select(x =&gt; x.Select(y =&gt; y.Item1).ToList()).ToList();
  List&lt;List&lt;int&gt;&gt; b = tuples.Select(x =&gt; x.Select(y =&gt; y.Item2).ToList()).ToList();
  List&lt;List&lt;int&gt;&gt; c = tuples.Select(x =&gt; x.Select(y =&gt; y.Item3).ToList()).ToList();
  </code></pre>
  
  <p>But, can I make all three lists at once using LINQ? Something like:</p>
  
  <pre><code>Tuple&lt;List&lt;List&lt;int&gt;&gt;, List&lt;List&lt;int&gt;&gt;, List&lt;List&lt;int&gt;&gt;&gt; splitted = tuples.Magic(...);
  </code></pre>
  
  <p><strong>Edit:</strong> (This is added after tymtam and Mong Zhu posted their answers)</p>
  
  <p>To be more clear, later when I said "at once", I was concerning performance. I don't really care about actual type of outcome and I don't have obsession with doing it in single line. </p>
  
  <p><strong>Performance-wise Comparison:</strong></p>
  
  <p>This is my code to compare splitting 1000 lists of 1000 tuples, (50 calls, 4000 sample/s):</p>
  
  <pre><code>private void Split_Loop(List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples)
  {
      List&lt;List&lt;int&gt;&gt; a = new List&lt;List&lt;int&gt;&gt;(tuples.Count);
      List&lt;List&lt;int&gt;&gt; b = new List&lt;List&lt;int&gt;&gt;(tuples.Count);
      List&lt;List&lt;int&gt;&gt; c = new List&lt;List&lt;int&gt;&gt;(tuples.Count);
      for (int i = 0; i &lt; tuples.Count; i++)
      {
          int n = tuples[i].Count;
          List&lt;int&gt; l1 = new List&lt;int&gt;(n);
          a.Add(l1);
          List&lt;int&gt; l2 = new List&lt;int&gt;(n);
          b.Add(l2);
          List&lt;int&gt; l3 = new List&lt;int&gt;(n);
          c.Add(l3);
  
          for (int j = 0; j &lt; n; j++)
          {
              l1.Add(tuples[i][j].Item1);
              l2.Add(tuples[i][j].Item2);
              l3.Add(tuples[i][j].Item3);
          }
      }
  }
  private void Split_Linq3(List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples)
  {
      List&lt;List&lt;int&gt;&gt; a = tuples.Select(x =&gt; x.Select(y =&gt; y.Item1).ToList()).ToList();
      List&lt;List&lt;int&gt;&gt; b = tuples.Select(x =&gt; x.Select(y =&gt; y.Item2).ToList()).ToList();
      List&lt;List&lt;int&gt;&gt; c = tuples.Select(x =&gt; x.Select(y =&gt; y.Item3).ToList()).ToList();
  }
  private void Split_tymtam(List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples)
  {
      IEnumerable&lt;List&lt;List&lt;int&gt;&gt;&gt; a = new Func&lt;Tuple&lt;int, int, int&gt;, int&gt;[]
          { t =&gt; t.Item1, t =&gt; t.Item2, t =&gt; t.Item3 }.
              Select(f =&gt; tuples.Select(x =&gt; x.Select(f).ToList()).ToList());
      List&lt;List&lt;List&lt;int&gt;&gt;&gt; b = a.ToList();
  }
  private void Split_Mong(List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples)
  {
      Func&lt;List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt;, Func&lt;Tuple&lt;int, int, int&gt;, int&gt;, List&lt;List&lt;int&gt;&gt;&gt; selectorGen = (x, t) =&gt; x.Select(y =&gt; y.Select(t).ToList()).ToList();
      Tuple&lt;List&lt;List&lt;int&gt;&gt;, List&lt;List&lt;int&gt;&gt;, List&lt;List&lt;int&gt;&gt;&gt; splitted = Tuple.Create(
              selectorGen(tuples, t =&gt; t.Item1),
              selectorGen(tuples, t =&gt; t.Item2),
              selectorGen(tuples, t =&gt; t.Item3));
  }
  private void button3_Click(object sender, EventArgs e)
  {
      int outer = 1000;
      int inner = 1000;
      List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt; tuples = new List&lt;List&lt;Tuple&lt;int, int, int&gt;&gt;&gt;(outer);
      for (int i = 0; i &lt; outer; i++)
      {
          List&lt;Tuple&lt;int, int, int&gt;&gt; list = new List&lt;Tuple&lt;int, int, int&gt;&gt;(inner);
          tuples.Add(list);
          for (int j = 0; j &lt; inner; j++)
          {
              Tuple&lt;int, int, int&gt; tuple = new Tuple&lt;int, int, int&gt;(i + j + 1, i + j + 2, i + j + 3);
              list.Add(tuple);
          }
      }
      for (int i = 0; i &lt; 50; i++)
      {
          Split_Loop(tuples);
          Split_Linq3(tuples);
          Split_tymtam(tuples);
          Split_Mong(tuples);
      }
  }
  </code></pre>
  
  <p>and this is the results:
  <a href="https://i.stack.imgur.com/sWDvE.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sWDvE.png" alt="enter image description here"></a></p>