如何使用Linq(Aggregate)折叠到列表?

时间:2014-02-24 21:26:01

标签: c# f#

如何转换以下F#(将整数转换为字符串并替换一些字符并将其反转,只是一个示例。我真正需要的是如何在C#中将List折叠到C#使用Aggregate

// Convert an integer to string, replace some characters and reverse it
let convert (aInt:int) =
    let m = [ '0', 'O'; '1', 'l'; '8', 'B'; ....] |> Map.ofList
    string aInt |> Seq.fold (fun a e -> m.[e]::a) [] |> String.Concat

每次在F#中调用函数m时,都会重新生成convert吗?

1 个答案:

答案 0 :(得分:5)

您无法直接将代码转换为C#,因为许多转换在C#中都不可用(至少在没有引用F#核心库的情况下)。

但是,以下内容将提供相同的结果:

static string Convert(int value)
{
    // use a Dictionary instead of F# Map
    var m = new Dictionary<char, char>
    {
        {'0', 'O'},
        {'1', '1'},
        {'8', 'B'}
    };

    // Convert to IEnumerable<char> directly from dictionary
    var valStrs = value.ToString().Select(c => m[c]);

    // Build results from characters
    return new String(valStrs.Reverse().ToArray());
}

请注意,您可以使用aggregate执行此操作,但您最终会做一些事情来改变聚合值,因此它的行为仍然与F#不同。此突变值可以是List<T>(如下所示),StringBuilder或您想要聚合的任何其他内容。我使用了List<T>因为这适用于任何类型(不仅仅是字符串/字符值),因为我怀疑这可能会理解如何从折叠转换为聚合,而不是手头的这个特定问题:

static string Convert(int value)
{
    var m = new Dictionary<char, char>
    {
        {'0', 'O'},
        {'1', '1'},
        {'8', 'B'}
    };

    var valStrs = value
        .ToString()
        .Reverse()
        .Select(c => m[c])
        .Aggregate(new List<char>(), (list, val) => { list.Add(val); return list;});
    return new String(valStrs.ToArray());
}

  

每次在F#中调用函数convert时都会重新生成吗?

没有。您可以在FSI中看到以下内容:

let convert (aInt:int) =
    let m = 
        printfn "m"
        [ '0', 'O'; '1', 'l'; '8', 'B'] |> Map.ofList
    string aInt |> Seq.fold (fun a e -> m.[e]::a) [] |> String.Concat

在FSI中调用convert 8811;;将输出:

m
val it : string = "llBB"