var square = x => x * x;
More properly we had:
var square = function(x) { return x * x; };
Anyway, that wasn't what was required; what was required was for a function which iterated over an array and returned the sum of all of the squares of each element in the array. This was the original function which required refactoring:
function sumSquares(numbers) { var total = 0; for (var i = 0; i < numbers.length; i++){ total += numbers[i] * numbers[i] } return total; } console.log(sumSquares([1,2,3])); // 14
For some reason, the for loop needed to be replaced with a function called each which looks like this:
function each(array, func) { for (var i = 0; i < array.length; i++) { func(array[i]); } }
Which is cool, but I quite like for loops, and while loops for that matter... ahh well.
So we were left with something like this:
function sumSquares(numbers) { var total = 0; each(numbers, function(element){ total += square(element) }); return total; } console.log(sumSquares([1,2,3])); // 14
Which works but I'm not overly happy with it. I can sort of see what the task is trying to get the student to understand but I'm not sure if it goes far enough, especially with the introduction of the array reduce method and most especially with its polyfill for when you're targeting an ancient browser:
// Production steps of ECMA-262, Edition 5, 15.4.4.21 // Reference: http://es5.github.io/#x15.4.4.21 if (!Array.prototype.reduce) { Array.prototype.reduce = function(callback /*, initialValue*/) { 'use strict'; if (this === null) { throw new TypeError('Array.prototype.reduce called on null or undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + ' is not a function'); } var t = Object(this), len = t.length >>> 0, k = 0, value; if (arguments.length == 2) { value = arguments[1]; } else { while (k < len && !(k in t)) { k++; } if (k >= len) { throw new TypeError('Reduce of empty array with no initial value'); } value = t[k++]; } for (; k < len; k++) { if (k in t) { value = callback(value, t[k], k, t); } } return value; }; }
Anyway, my preferred quick and dirty refactoring would be this:
console.log([1,2,3].reduce((p, c) => p + (c * c), 0));
It's always nice when you can replace a shed load of stuff with a single liner, I blame Empire of Code for getting me that way ;-)
We can test it easily enough using this:
console.log([1,2,3].reduce((p,c)=>p+(c*c),0) === (1*1)+(2*2)+(3*3)); // true
I guess that the beauty of Javascript is that there are so very many ways of doing any one thing. We could re-write it using typescript like this:
var sumSquares = (arr: number[]): number => arr.reduce((a: number, b: number) => a + (b * b), 0);
console.log(sumSquares([1, 2, 3])); // 14
Which would get compiled to this Javascript:
var sumSquares = function (arr) { return arr.reduce(function (a, b) { return a + (b * b); }, 0); }; console.log(sumSquares([1, 2, 3])); // 14
Anyway, that was fun and I learnt something - not least that there wee drop of madness where the function gets called within the each function - I'm going to have to ponder that bit some more as I originally just wanted to pass the square function as the second parameter but then got confused in that it didn't return anything and ended up re-writing it so that it did, adding it as a call within a function works a treat though.
No comments:
Post a Comment