懒惰的组合

时间:2014-11-14 14:14:47

标签: c# linq lazy-evaluation

我正在寻找一种更懒惰/ IEnumerable /更清洁的方式来执行以下操作。我特别不满意使用helper和聚合。

有关如何修改代码以使其成为可能的任何提示?

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>>();

1 个答案:

答案 0 :(得分: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();
        }
    }
}