title: Calculating an index from a combination of indexes
body: <p>I have a 2D list that might look something like this:</p>
  
  <pre><code>List&lt;List&lt;object&gt;&gt; myCategories;
  </code></pre>
  
  <p>Now each inner list is a list of options in a category. It's a jagged collection, so there might be <code>2</code> options in the first list and <code>4</code> in the second.</p>
  
  <p>Now I'm transforming that into rows for each combination of categories so, in my example, I'd expect to end up with <code>2 * 4 = 8</code> rows in total. Which would be arranged like so:</p>
  
  <pre><code>Row | Cat 0    | Cat 1
   0  | Item 0_0 | Item 1_0
   1  | Item 0_0 | Item 1_1
   2  | Item 0_0 | Item 1_2
   3  | Item 0_0 | Item 1_3
   4  | Item 0_1 | Item 1_0
   5  | Item 0_1 | Item 1_1
   6  | Item 0_1 | Item 1_2
   7  | Item 0_1 | Item 1_3
  </code></pre>
  
  <p>Now what I'm struggling with is, given an array of indexes into each category, say <code>[1,2]</code>, the row I need would be <code>6</code> because that's where I have item <code>1</code> from category <code>0</code> and item <code>2</code> from category <code>1</code>. </p>
  
  <p>I had something like this (where <code>idx</code> is a <code>List&lt;int&gt;</code> with my indexes):</p>
  
  <pre><code>var rowIdx = idx.Select((v, i) =&gt; new { v, i }).Aggregate(0, (c, n) =&gt;
  {
      c += n.v * Math.Max(1, myCategories.Skip(n.i + 1).Sum(a =&gt; a.Count));
      return c;
  });
  </code></pre>
  
  <p>Which works great with 1 or 2 categories, but falls apart once you hit three categories. For example, if you have <code>4</code>,<code>1</code> and <code>1</code> as the <code>Count</code> of each category, and you are looking for the row corresponding to item <code>1</code> in category <code>0</code> (and obviously <code>0</code> and <code>0</code> in the other two, because there is only one choice), you end up with an index of <code>2</code> instead of <code>1</code>.</p>
  
  <p>Here's a <a href="https://dotnetfiddle.net/n1J1Qj" rel="nofollow">fiddle</a>:</p>
  
  <pre><code>var categories = new List&lt;List&lt;object&gt;&gt;()
  {
      new List&lt;object&gt;(){ null, null },
      new List&lt;object&gt;(){ null, null, null, null }
  };
  
  var idx = new List&lt;int&gt;() { 1, 2 };
  
  var rowIdx = CalcIndex(categories,idx);
  
  Console.WriteLine(rowIdx);      // outputs 6 as expected
  
  categories = new List&lt;List&lt;object&gt;&gt;()
  {
      new List&lt;object&gt;() { null, null, null, null },
      new List&lt;object&gt;() { null },
      new List&lt;object&gt;() { null }
  };
  
  idx = new List&lt;int&gt;() { 2, 0, 0 };
  
  rowIdx = CalcIndex(categories,idx);
  
  Console.WriteLine(rowIdx);      // should give 2, but gives 4 instead.
  
  public static int CalcIndex(List&lt;List&lt;object&gt;&gt; categories, List&lt;int&gt; idx) 
  {
      return idx.Select((v, i) =&gt; new { v, i }).Aggregate(0, (c, n) =&gt;
      {
          c += n.v * Math.Max(1, categories.Skip(n.i + 1).Sum(a =&gt; a.Count));
          return c;
      });
  }
  </code></pre>