在遍历 IEnumerable 的扩展中,将等于运算符转换为 Func<bool> 作为参数

Convert an equals operator to a Func<bool> for argument in an extension that iterates over IEnumerable

我有扩展功能:

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} 并且你要 运行 迭代方法并将内容放入字符串中,你会期望:"1100"

好吧,如果不编写扩展方法,这样做会非常简单。只需使用 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 方法都以某种方式迭代。

虽然该函数本身有点古怪,但您可以让它适用于任何条件,如下所示:

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

但是,如您所见,实现没有声明那么复杂,因此可能不值得使用此方法。