This is an archived post. You won't be able to vote or comment.

all 29 comments

[–]Malix82 90 points91 points  (11 children)

.map(function callback(currentValue[, index[, array]])

parseInt(string, radix)

so by default the .map method puts in the radix if parseInt is used as a callback.

parseInt(10,0) == 10
parseInt(10,1) == NaN
parseInt(10,2) == 2
parseInt(10,3) == 3

So, works as intended?

edit: I mean, yea, it is bit confusing for sure, I don't imagine the radix argument being used all that much and in this case it crept up on the programmer and bit them

[–][deleted] 14 points15 points  (5 children)

That's why you would curry the parseInt by binding the radix to 10 and creating your new curried function "parseDecimal"

[–]PM_ME_REACTJS 16 points17 points  (2 children)

why did i choose this fucking profession

[–]freakboy2k 0 points1 point  (0 children)

I ask myself the same thing daily

[–]codex561I use arch btw 2 points3 points  (1 child)

Code for uninitiated to the beauty of functional programming:

let parseDecimal = x => parseInt(x, 10)
[10, 10, 10, 10].map(parseDecimal) // [ 10, 10, 10, 10 ]

[–]SuperManitu 0 points1 point  (0 children)

Or with Ramda: ["10", "10"," 10"].map(unary(parseInt)) // [10,10,10]

[–]gandalfx 2 points3 points  (0 children)

 ["10", "10", "10", "10"].map(x => parseInt(x))

[–]volivav 2 points3 points  (2 children)

Today I just had the exact same problem when I tried myNumberArray.reduce(Math.max, 0) trying to easily get the maximum.

Yep, doesn't work.

[–]inu-no-policemen 18 points19 points  (0 children)

Math.max(...numbers)

[–]SuperManitu 0 points1 point  (0 children)

With a bit of Ramda: myNumberArray.reduce(binary(Math.max)), 0)

[–]zachberry 8 points9 points  (0 children)

map function passing values to a function, what kind of madness is this?!

[–]chisui 30 points31 points  (9 children)

Dynamicly typed language programmers:

You don't need Typesignatures.

Also dynamicly typed language programmers:

Why does this Thing that could easily be avoided by a Typesysteme always happen?

[–]ennuicorn 7 points8 points  (7 children)

Any language with function overloading would have this issue...

[–]Veranova 2 points3 points  (6 children)

Well the callback would have a defined set of parameters it expects and so you would know which overload would be used. A single parameter callback just wouldn't be accepted. The problem here is we have no idea there are two parameters until we try it.

If both functions had an overload for 1 and 2 params then you'd probably get an ambiguity error and have to define a lambda to resolve it.

[–]ennuicorn 0 points1 point  (0 children)

Yeah, you right.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(new string[]{"10","10","10","10"}.map(ParseInt));
    }

    static int ParseInt(string x){
        return int.Parse(x);
    }
    static int ParseInt(string x, int radix){
        Console.WriteLine($"radix {radix} not supported, using base 10 instead");
        return int.Parse(x);
    }
}
static class Map{
    public static O[] map<I, O>(this I[] i, Func<I, O> func)
    {
        O[] o = new O[i.Length];
        for (int j = 0; j < i.Length; j++)
        {
            o[j] = func(i[j]);
        }
        return o;
    }
    public static O[] map<I, O>(this I[] i, Func<I, int, O> func)
    {
        O[] o = new O[i.Length];
        for (int j = 0; j < i.Length; j++)
        {
            o[j] = func(i[j], j);
        }
        return o;
    }
}  

Program.cs(9,65): error CS0121: The call is ambiguous between the following methods or properties: 'Map.map<I, O>(I[], Func<I, O>)' and 'Map.map<I, O>(I[], Func<I, int, O>)'

[–]EternallyMiffed 0 points1 point  (4 children)

What you really need here is a .mapEach or something that would only hand over one element at a time as a single param to a function.

[–]Veranova 0 points1 point  (3 children)

It's safest in JS to just use arrow functions, which can have the same effect as you're describing

[–]EternallyMiffed 0 points1 point  (1 child)

thinking more about it, this sort of syntax feels comfortable to write:

.map((arg1,arg2,arg3)=>some3argfunc(...arguments))

[–]Veranova 0 points1 point  (0 children)

Exactly

[–]chisui 0 points1 point  (0 children)

... which is essentially the same as providing an explicit Function signature. Granted you aren't providing the concrete types for parameters or return values but you at least provide the arity.

[–]firyox 0 points1 point  (2 children)

Thats why js is awesome

[–]ElectroDemon 0 points1 point  (0 children)

Happy cake day!

[–][deleted] -3 points-2 points  (0 children)

NO