Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's a pure Linq solution, inspired by Eric Lippert's <a href="http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx" rel="nofollow">blog post</a> about computing a cartesian product. I modified the <code>CartesianProduct</code> method slightly so that it returns combinations:</p> <pre class="lang-cs prettyprint-override"><code>public static IEnumerable&lt;IEnumerable&lt;T&gt;&gt; Combinations&lt;T&gt;(this IEnumerable&lt;IEnumerable&lt;T&gt;&gt; sequences) { IEnumerable&lt;IEnumerable&lt;T&gt;&gt; emptyProduct = new[] { Enumerable.Empty&lt;T&gt;() }; return sequences.Aggregate( emptyProduct, (accumulator, sequence) =&gt; from accseq in accumulator // Exclude items that were already picked from item in sequence.Except(accseq) // Enforce ascending order to avoid same sequence in different order where !accseq.Any() || Comparer&lt;T&gt;.Default.Compare(item, accseq.Last()) &gt; 0 select accseq.Concat(new[] {item})).ToArray(); } </code></pre> <p>Based on this extension method, you can produce the desired result as follows:</p> <pre class="lang-cs prettyprint-override"><code>IEnumerable&lt;string&gt; items = new[] {"Coffee", "Tea", "Milk"}; IEnumerable&lt;IEnumerable&lt;string&gt;&gt; result = Enumerable.Range(1, items.Count()) .Aggregate( Enumerable.Empty&lt;IEnumerable&lt;string&gt;&gt;(), (acc, i) =&gt; acc.Concat(Enumerable.Repeat(items, i).Combinations())); </code></pre> <p>(it concatenates all combinations of 1, 2... N items)</p> <p>Note that it's probably not a very efficient solution, but I think it's an interesting use of Linq...</p> <hr> <p>EDIT: here's a new version of the <code>Combinations</code> method that maintains the original order:</p> <pre class="lang-cs prettyprint-override"><code>public static IEnumerable&lt;IEnumerable&lt;T&gt;&gt; Combinations&lt;T&gt;(this IEnumerable&lt;IEnumerable&lt;T&gt;&gt; sequences) { var indexedSequences = sequences.Select(seq =&gt; seq.Select((item, idx) =&gt; new IndexedItem&lt;T&gt;(item, idx))); IEnumerable&lt;IEnumerable&lt;IndexedItem&lt;T&gt;&gt;&gt; emptyProduct = new[] { Enumerable.Empty&lt;IndexedItem&lt;T&gt;&gt;() }; var indexedResult = indexedSequences.Aggregate( emptyProduct, (accumulator, sequence) =&gt; from accseq in accumulator // Exclude items that were already picked from item in sequence.Except(accseq) // Enforce ascending order of indexes to avoid same sequence in different order where !accseq.Any() || item.Index &gt; accseq.Last().Index select accseq.Concat(new[] {item})).ToArray(); return indexedResult.Select(seq =&gt; seq.Select(i =&gt; i.Item)); } class IndexedItem&lt;T&gt; { public IndexedItem(T item, int index) { this.Item = item; this.Index = index; } public T Item { get; private set; } public int Index { get; set; } } </code></pre> <p>Probably even more inefficient than the previous version, but it gets the job done...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload