File tree 1 file changed +39
-0
lines changed
1 file changed +39
-0
lines changed Original file line number Diff line number Diff line change @@ -418,6 +418,45 @@ public static IEnumerable<IEnumerable<T>> PermutationsDistinct<T>(this IEnumerab
418
418
elemList . Add ( elem ) ;
419
419
}
420
420
}
421
+
422
+ // "limit" is non-optional here because 0 would just reutrn basically
423
+ // the original list.
424
+ //
425
+ // Also, this immediately enumerates everything because otherwise it
426
+ // would carry a risk of multiple enumeration.
427
+ public static IEnumerable < IEnumerable < T > > Combinations < T > ( this IEnumerable < T > elems , int limit )
428
+ {
429
+ T [ ] elemArray = elems . ToArray ( ) ;
430
+
431
+ if ( limit <= 0 ) limit += elemArray . Length ;
432
+ if ( limit < 0 ) return Enumerable . Empty < IEnumerable < T > > ( ) ;
433
+ if ( limit >= elemArray . Length ) return EnumerableUtils . Of ( elems ) ;
434
+
435
+ return Combs ( elemArray , limit ) ;
436
+ }
437
+
438
+ static IEnumerable < IEnumerable < T > > Combs < T > ( IEnumerable < T > elemList , int keep )
439
+ {
440
+ int skips = elemList . Count ( ) - keep ;
441
+ if ( skips == 0 )
442
+ {
443
+ yield return elemList ;
444
+ yield break ;
445
+ }
446
+
447
+ foreach ( ( T elem , int i ) in elemList . Take ( skips + 1 ) . WithIndex ( ) )
448
+ {
449
+ if ( keep == 1 ) yield return EnumerableUtils . Of ( elem ) ;
450
+ else
451
+ {
452
+ foreach ( IEnumerable < T > comb in Combs ( elemList . Skip ( i + 1 ) , keep - 1 ) )
453
+ {
454
+ yield return comb . Prepend ( elem ) ;
455
+ }
456
+ }
457
+ }
458
+ }
459
+
421
460
public static IEnumerable < T > Repeat < T > ( this IEnumerable < T > seq , int count )
422
461
{
423
462
foreach ( int i in Enumerable . Range ( 0 , count ) )
You can’t perform that action at this time.
0 commit comments