2014-11-14 60 views
0

我正在尋找一個比較懶惰/ IEnumerable的/清潔執行以下操作的方式。我特別不喜歡使用helper和Aggregate。懶組合

如何修改代碼以使人們有可能任何提示嗎?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Test1 
{ 
    class Program 
    { 
     static void PrintOut<T>(IEnumerable<IEnumerable<T>> data) 
     { 
      foreach (var item in data) 
      { 
       string output = "-"; 
       if (item != null) 
        output = string.Join(",", item.Select(x => (x == null) ? "-" : x.ToString())); 
       Console.WriteLine(output); 
      } 
     } 


     static IEnumerable<T> helper<T>(IEnumerable<T> orig, T toAdd) 
     { 
      if (orig != null) 
       foreach (var item in orig) 
        yield return item; 
      yield return toAdd; 
      yield break; 
     } 


     static IEnumerable<IEnumerable<T>> helper2<T>(IEnumerable<IEnumerable<T>> input) where T : class 
     { 
      var initalAcc = new List<IEnumerable<T>> { }; 
      var result = input.Aggregate(initalAcc, 
       (acc, choiceSet) => 
        acc.DefaultIfEmpty() 
         .SelectMany((chosen) => (choiceSet ?? new List<T> { }).DefaultIfEmpty().Select(choice => helper(chosen, choice))).ToList() 
      ); 
      return result; 
     } 

     static void Main(string[] args) 
     { 
      var preCombination = new List<List<string>> { 
       new List<string> {"1","2"}, 
       new List<string> {"3"}, 
       new List<string> {"4","5"}, 
       null, 
       new List<string> {"6","7"} 
      }; 
      var postCombination = helper2(preCombination); 

      PrintOut(preCombination); 
      Console.WriteLine(); 
      PrintOut(postCombination); 
      Console.ReadLine(); 
     } 
    } 
} 

這裏是預期輸出

1,2 
3 
4,5 
- 
6,7 

1,3,4,-,6 
1,3,4,-,7 
1,3,5,-,6 
1,3,5,-,7 
2,3,4,-,6 
2,3,4,-,7 
2,3,5,-,6 
2,3,5,-,7 

我已經改變了initalAcc現在

var initalAcc = Enumerable.Empty<IEnumerable<T>>(); 
+0

爲什麼向下票呢? – 2014-11-14 14:19:52

+0

helper2應該完成什麼? – Shlomo 2014-11-14 14:27:00

+0

除空校驗'helper'相同'orig.Concat(Enumerable.Repeat(TOADD,1));'。 – juharr 2014-11-14 14:39:34

回答

1

在這裏你去。 ConcatItemYield替換助手。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace Test1 
{ 
    class Program 
    { 
     static void PrintOut<T>(IEnumerable<IEnumerable<T>> data) 
     { 
      foreach (var item in data) 
      { 
       string output = "-"; 
       if (item != null) 
        output = string.Join(",", item.Select(x => (x == null) ? "-" : x.ToString())); 
       Console.WriteLine(output); 
      } 
     } 


     static IEnumerable<T> Yield<T>(T item) 
     { 
      yield return item; 
     } 


     static IEnumerable<T> ConcatItem<T>(IEnumerable<T> enumerable, T item) 
     { 
      return enumerable == null ? Yield(item) : enumerable.Concat(Yield(item)); 
     } 

     static IEnumerable<IEnumerable<T>> helper2<T>(IEnumerable<IEnumerable<T>> input) where T : class 
     { 
      var initalAcc = Enumerable.Empty<IEnumerable<T>>(); 
      var result = input.Aggregate(initalAcc, 
       (acc, choiceSet) => 
        acc.DefaultIfEmpty() 
         .SelectMany((chosen) => (choiceSet ?? Enumerable.Empty<T>()).DefaultIfEmpty().Select(choice => ConcatItem(chosen, choice))) 
      ); 
      return result; 
     } 

     static void Main(string[] args) 
     { 
      var preCombination = new List<List<string>> { 
       new List<string> {"1","2"}, 
       new List<string> {"3"}, 
       new List<string> {"4","5"}, 
       null, 
       new List<string> {"6","7"}, 
      }; 
      var postCombination = helper2(preCombination); 

      PrintOut(preCombination); 
      Console.WriteLine(); 
      PrintOut(postCombination); 
      Console.ReadLine(); 
     } 
    } 
} 
+1

'收率(項目);'相同'Enumerable.Repeat(項目,1);' – juharr 2014-11-14 14:43:50

+0

是。國際海事組織,應該有一個Enumerable.Return(或收益)來匹配經典monad函數,但我離題了。 – Shlomo 2014-11-14 15:12:06