ca9163d9
ca9163d9

Reputation: 29249

How to fold to list using Linq (Aggregate)?

How do I convert the following F# (which converts an integer to string and replace some characters and reverse it, just an example. What I really need is how to do fold to List in C#) to C# using 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

Will m be regenerated every time when the function convert is called in F#?

Upvotes: 3

Views: 1976

Answers (1)

Reed Copsey
Reed Copsey

Reputation: 564931

You can't directly convert the code to C#, as many of the conversions aren't available in C# (at least not without referencing F#'s core libraries).

However, the following will provide equivalent results:

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

Note that you can do this with aggregate, but you'd end up doing something to mutate the aggregation value, so it still behaves differently than F#. This mutated value could be a List<T> (as below), a StringBuilder, or anything else you want to aggregate. I used a List<T> as this works with any type (not just string/char values), since I suspect this is likely to understand how to convert from a fold to aggregate, not this specific problem at hand:

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

Will m be regenerated every time when the function convert is called in F#?

No. You can see that from the following in 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

Calling convert 8811;; in FSI will output:

m
val it : string = "llBB"

Upvotes: 5

Related Questions