Sweepster
Sweepster

Reputation: 1949

How can I convert this arrow function to a standard function?

I have an arrow function, offered graciously by Ele of the community here, but for the life of me, I can't understand it:

let isValid = function (arr, arr2) {
    let sum = (array, n) => array.reduce((a, an) => a + (an === n), 0);  
     return !arr2.some(n => !arr.some(an => an === n && sum(arr, an) === sum(arr2, n)))
};

Would someone be so kind as to translate this into a standard function so that I can follow it on my skill level?

Thank you.

My assumption:

function isValid (arr, arr2) {
    ...this is where i'm lost
}

Upvotes: 2

Views: 888

Answers (3)

Mitya
Mitya

Reputation: 34556

Your assumption is correct for the outer function. The first line inside it would become:

function sum(array, n) {
    return array.reduce(function(a, an) {
        return a + (an === n);
    }, 0);

Have a read about Arrow Functions and how they differ from conventional function declarations. Mostly (but not completely), they're just syntactical sugar vs. conventional functions.

They differ most markedly in terms of context, i.e. what this points to inside the function body. Arrow functions always run in the outer, prevailing context in which the function was declared. Conventional functions, e.g. via bind(), can be repointed to a different context.

let foo = function() {
    let bar = () => this;
    return bar();
}.bind('a');
foo(); //'a', because foo()'s context is 'a'

So how about that sugar? It can look confusing at first, especially when you have multiple arrow functions in one line. One key thing to remember is that they're just implicit shorthand for things you used to have to code manually.

let foo = a => a+1;

Is the same as

function foo2(a) { return a + 1; }

(The hoisting will be different, but that's a bit beyond the scope of this answer.)

One thing we can tell from the above is there is that, where the part after => is a single statement, it's interpreted as a return value, without us having to actually write return.

foo(1); //2

This is great for simple functions that do one job expressable in one line of code. If you need more verbose functions you enclose the code in {} as usual.

let foo3 = a => {
    return a+1;
};

This again works identically to the foo and foo2 above.

And so, finally, breaking down that fearsome line:

    let sum = (array, n) => array.reduce((a, an) => a + (an === n), 0);  

It says:

  • assign a function to the local scope variable sum
  • it accepts two arguments, array and n
  • it has one job to do, expressable as one line of code and so no need for binding { and } for the function body. That job is to call reduce() and return (implicitly) the value
  • The first argument to reduce, the callback, accepts two arguemnts, a and an
  • This callback, like the one to reduce, also has just one job to do, and that job is to return the value of a + (an === n)

One final word on the sugar, which you may have spotted above, is that, with arrow functions, if only a single argument is accepted you don't need to wrap it in brackets. Multiple arguments are, though, and comma-separated as usual.

let foo = single_arg => alert(1);
let foo2 = (arg1, arg2) => alert(2);

Hope this helps.

Upvotes: 5

Ele
Ele

Reputation: 33726

That approach uses a lot of arrow functions, and can be translated to the following standard function declarations:

let isValid = function(arr, arr2) {
  let sum = function (array, n) {
    return array.reduce(function(a, an) {
      return a + (an === n); // coercion -> true = 1, false = 0
    }, 0);
  };

  return !arr2.some(function(n) {
    let sum2 = sum(arr2, n);
    return !arr.some(function(an) { 
      return an === n && sum(arr, an) === sum2;
    });
  });
};

Upvotes: 4

diogenesgg
diogenesgg

Reputation: 2839

You can use https://babeljs.io/ to compile from this new javscript to "old" javascript. You can try it directly on its home page.

Here's the output it gives:

var isValid = function isValid(arr, arr2) {
  var sum = function sum(array, n) {
    return array.reduce(function (a, an) {
      return a + (an === n);
    }, 0);
  };

  return !arr2.some(function (n) {
    return !arr.some(function (an) {
      return an === n && sum(arr, an) === sum(arr2, n);
    });
  });
};

Upvotes: 5

Related Questions