1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

「filterM で powerset」をC#らしく

Last updated at Posted at 2012-08-16

前回の 『「filterM で powerset」をC#に翻訳』はHaskellからの翻訳なのでC#的にいろいろ無理があった。特に再帰のところ。
熟練した C# 使いは再帰を書かない? その通り。ではどうするか。Aggregateを使う。

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var array = new[] { 1, 2, 3, 4, 5 };
        Func<int, IEnumerable<bool>> pred = x => new[] { true, false };

        foreach (var l in array.WhereMany(pred))
        {
            Console.WriteLine(l.ToStringEx());
        }
    }
}

public static class EnumerableEx
{
    public static IEnumerable<IEnumerable<T>> WhereMany<T>(
        this IEnumerable<T> source,
        Func<T, IEnumerable<bool>> predicates)
    {
        return source.Aggregate(
            Enumerable.Repeat(new LinkedList<T>(), 1),
            (acc, x) => acc.SelectMany(q => Accumulate(q, x, predicates))
        );
    }

    private static IEnumerable<LinkedList<T>> Accumulate<T>(
        LinkedList<T> q,
        T x,
        Func<T, IEnumerable<bool>> predicates)
    {
        foreach(var b in predicates(x))
        {
            if (b)
            {
                q.AddLast(x);
                yield return q;
                q.RemoveLast();
            }
            else
            {
                yield return q;
            }
        }
    }

    public static string ToStringEx<T>(this IEnumerable<T> source)
    {
        var strings = source.Select(x => x.ToString());
        return "[" + string.Join(", ", strings) + "]";
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?