将一个等于运算符转换为一个Func <bool>,用于迭代IEnumerable

时间:2017-06-24 01:10:19

标签: c# list foreach extension-methods

我有一个扩展功能:

public static IEnumerable<B> iterate<T, B>(this IEnumerable<T> source, 
Func<bool> condition, B TAddT, B TAddF)
    {
        foreach(T a in source)
        {
            if (condition()) yield return TAddT;
            else yield return TAddF;
        }
    }

我有一些像这样的代码:

List<bool> bar = new List<bool>(); //Supposed to be binary digits
//add some stuff to bar
string a = new string (bar.iterate<bool, char>(a == true, '1', '0')); //Convert a true to a 1, and a false to a 0

我将如何使这项工作?我不知道如何将a == true转换为Func<bool>

IE:如果你有List<bool> bar包含:{true, true, false, false}并且你要运行iterate方法并将内容放入一个字符串中,你会期望:"1100"

2 个答案:

答案 0 :(得分:2)

在没有编写扩展方法的情况下,它很简单。只需使用select和三元运算符。

var foo = bar.Select( a => a ? '1': '0');

如果您坚持为此编写扩展方法,我猜它看起来像这样:

static IEnumerable<char> Iterate(this IEnumerable<bool> source)
{
    return source.Select( a => a ? '1' : '0');
}

如果您想在类型和价值方面保持灵活性:

static IEnumerable<TOut> Iterate<TOut>(this IEnumerable<TIn> source, 
                                       Func<TIn, TOut> converter)
{
    return source.Select( a => converter(a));
}

并用

调用它
var foo = bar.Iterate(a => a ? '1' : '0');

如果我想要完全实现你的想法,那就是:

static IEnumerable<TOut> Iterate<TOut>(this IEnumerable<TIn> source, 
                                       Func<TIn, bool> decider,
                                       TOut resultIfTrue,
                                       TOut resultIfFalse)
{
    return source.Select( a => decider(a) ? resultIfTrue : resultIfFalse);
}

并用

调用它
var foo = bar.Iterate<char>(a => a, '1', '0');

P.S。 Iterate是一个LINQ扩展方法的可怕名称,因为所有LINQ方法都以某种方式迭代。

答案 1 :(得分:0)

虽然这个功能本身有点时髦,但你可以让它适用于任何条件:

IEnumerable<TOut> SelectLeftRight<TSource, TOut>(
    this IEnumerable<TSource> source, 
    Func<TSource, bool> selector, 
    TOut left, 
    TOut right) 
{
    return source.Select(input => selector(input) ? left : right);
}

用法:

bool[] source =  { true, false };
var left = '1';
var right = '0';

var str = new string(source.SelectLeftRight(a => a, left, right));

还可以使用其他一些数据类型:

int[] source =  { 5, 3 };
var left = '1';
var right = '0';

var str = new string(source.SelectLeftRight(a => a > 4, left, right));

但是,正如您所看到的,实现不如声明复杂,因此使用此方法可能不值得。