title: Linq group by, order by values
body: <p>I need help
  I have Table:</p>
  
  <pre><code>   Id          Day                 Group       Value 
   -------------------------------------------------
     1           2016-10-11          1           10.5
     2           2016-10-11          1           10.8
     3           2016-10-11          1           10.7
     4           2016-10-11          1           10.6
     5           2016-10-11          1           10.5
     6           2016-10-11          1           10.4
     7           2016-10-11          1           10.8
     8           2016-10-11          1           10.2
     9           2016-10-11          1           10.0
     10          2016-10-11          1           10.9
     11          2016-10-11          2           10.1
     12          2016-10-11          2           10.0
     13          2016-10-11          2           10.1
     14          2016-10-11          2           10.6
     15          2016-10-11          2           10.7
     16          2016-10-11          2           10.2
     17          2016-10-11          2           10.0
     18          2016-10-11          2           10.5
     19          2016-10-11          2           10.5
     20          2016-10-11          2           10.8
     21          2016-10-12          1           11.1
     22          2016-10-12          1           11.7
     23          2016-10-12          1           11.0
     24          2016-10-12          1           11.4
     25          2016-10-12          1           11.7
     26          2016-10-12          1           11.8
     27          2016-10-12          1           11.1
     28          2016-10-12          1           11.1
     29          2016-10-12          1           11.4
     30          2016-10-12          1           11.6
     31          2016-10-12          2           11.9 
     32          2016-10-12          2           11.6
     ...
  </code></pre>
  
  <p>And I want </p>
  
  <ul>
  <li>order by Value</li>
  <li>group by Group</li>
  <li>group by Day</li>
  <li>and get only value like:</li>
  </ul>
  
  <p><code>[[[10.5,10.8],[10.0,10.1]],[[11.1,11.7],[11.6,11.9]]]</code> (example)</p>
  
  <p>Respectively I need work with this value more, when I get value like example I get more value in Day. And then I split this batch to 4 batch and then I choose just first value from every group. So I will have 4 value for every Group and for 1 Day I will have 2 batch and every batch will have 4 value. And because I need have 5 value like last value in every batch I find Max Value and add it to batch with 4 value. I don’t know if you understand so there is my code:</p>
  
  <pre><code>    var valueList = await Task.Factory.StartNew(() =&gt;
  
      (
          from pv in db.Values
          where DbFunctions.TruncateTime(pv.Day) &gt;= startDate      
          &amp;&amp; DbFunctions.TruncateTime(pv.Day) &lt;= endDate           
          orderby pv.Value
          //group pv by pv.Day into gpv
          select pv
      ));
  
  var group1 = await Task.Factory.StartNew(() =&gt; (
  (
      from vl in valueList
      where vl.Group == 1
      select vl) 
  ));
  
  var group2 = await Task.Factory.StartNew(() =&gt;
  (
      from vl in valueList
      where vl.Group == 2
      select vl
  ));
  
  var group3 = await Task.Factory.StartNew(() =&gt;
  (
      from vl in valueList
      where vl.Group == 3
      select vl 
  ));
  
  
  var group1Split = group1.Split(group1.Count() / 4 + 1).Select(x =&gt; x.First());
  var group1Max = group1.Max();
  var group2Split = group2.Split(group2.Count() / 4 + 1).Select(x =&gt; x.First());
  var group2Max = group2.Max();
  var group3Split = group3.Split(group3.Count() / 4 + 1).Select(x =&gt; x.First());
  var group3Max = group3.Max();
  
  var group1Values = group1Split.Concat(group1Max);
  var group2Values = group2Split.Concat(group2Max);
  var group3Values = group3Split.Concat(group3Max);
  
  var groupAllValues = group1Values.Concat(group2Values).Concat(group3Values);
  var groupSplitAllValues = groupAllValues.Split(5);
  
  return Request.CreateResponse(HttpStatusCode.OK, groupSplitAllValues.ToList());
  </code></pre>
  
  <p>Update:</p>
  
  <p>this work:</p>
  
  <pre><code>var result = db.Values
      .Where(x =&gt; (DbFunctions.TruncateTime(x.Day)) &gt;= startDate
      &amp;&amp; (DbFunctions.TruncateTime(x.Day)) &lt;= endDate)
     .GroupBy(x =&gt; new { Day = x.Day, Group = x.Group })
     .Select(x =&gt; x.Select(y =&gt; y.Value).OrderBy(z =&gt; z).ToList()).ToList();
  </code></pre>
  
  <p>I get this:</p>
  
  <pre><code>[
  [10.0, 10.2, 10.4, 10.5, 10.5, 10.6, 10.7, 10.8, 10.8, 10.9],
  [10.0, 10.0, 10.1, 10.1, 10.2, 10.5, 10.5, 10.6, 10.7, 10.8],
  [11.0, 11.1, 11.1, 11.1, 11.4, 11.4, 11.6, 11.7, 11.7, 11.8],
  [...]
  ]
  </code></pre>
  
  <p>But I need split every batch to in this case 2 part and select first value from this part. So I will have 2 value and then I want concat to 2 value max value from this batch so for this example my final result will be:</p>
  
  <pre><code>[
  [10.0, 10.6, 10.9],
  [10.0, 10.2, 10.8],
  [11.0, 11.4, 11.8],
  [...]
  ]
  </code></pre>
  
  <p>For splitting I use this method:</p>
  
  <pre><code>public static IEnumerable&lt;IEnumerable&lt;T&gt;&gt; Split&lt;T&gt;(this IEnumerable&lt;T&gt; source, int length)
          {
              if (length &lt;= 0)
                  throw new ArgumentOutOfRangeException("length");
  
              var section = new List&lt;T&gt;(length);
  
              foreach (var item in source)
              {
                  section.Add(item);
  
                  if (section.Count == length)
                  {
                      yield return section.AsReadOnly();
                      section = new List&lt;T&gt;(length);
                  }
              }
  
              if (section.Count &gt; 0)
                  yield return section.AsReadOnly();
          }
  </code></pre>