[c#]懒惰的组合

标签: Linq C#
发布时间: 2017/2/28 22:40:48
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我正在做以下更懒惰/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:

给你。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();
        }
    }
}
赞助商