I'm trying to solve a coding challenge it gives me an array and waits for the answer ,then gives me the next array and so on. https://www.codewars.com/kata/5648b12ce68d9daa6b000099/train/javascript
I am trying to take this input: var busStops = [[10,0],[3,5],[5,8]] and return 5. the code is supposed to add the first in each pair to a total while subtracting the second in each pair from the total eg: 10 - 0 3 - 5 5 - 8 = 5
First my code loops through the inner arrays and outer array ,pushing it into myarr as a regular array eg: [10,0,3,5,5,8].
It then adds the value if it is index is 0 or even and subtracts it if the index is odd. This actually works! Until it is given a second array eg: [[3,0],[9,1],[4,10],[12,2],[6,1],[7,10]]
It is still calculating the total correctly but is still remembering the total from the first array meaning it is returning 22 instead of 17
Why? There is a var answer = 0 that is being executed ahead of the second loop It should forget the value of the previous answer. Right?
Edit: I figured out my problem. I just needed to empty myarr after the total was calculated!
let myarr = [];
var number = function (busStops) {
for (var i = 0; i < busStops.length; i ) {
for (var j = 0; j < busStops[i].length; j ) {
/*console.log(busStops[i][j]);*/
myarr.push(busStops[i][j]);
}
}
console.log("test");
var answer = 0;
console.log("test again");
for (let t = 0; t < myarr.length; t ) {
if (t == 0 || t % 2 == 0) {
answer = answer myarr[t];
} else {
answer = answer - myarr[t];
}
}
console.log(answer);
return answer;
};
CodePudding user response:
The task at your hand tries to somehow find a value (an integer) from an array of arrays (multidimensional array). That task seems to be reducing that multidimensional array into a single integer.
Luckily, JavaScript
has some powerful array methods and one of them is the reduce
method:
The
reduce()
method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value. Source: MDN
The reduce
method tries to reduce
an array's elements into a single value and in your case we want to reduce that multidimensional array into a single value that is the number persons who are still in the bus.
Before typing some code, let's dig a bit deeper into the reduce
method:
- It accepts 2 parameters, a callback function that acts as the reducer and the initial value to be used in the first iteration of the
reduce
method. - The reducer callback function, on its own, accepts 4 parameters that are supplied by the
reduce
method. You may learn more about those parameters here as am only going to focus on the first 2 parameters the reducer accepts:previousValue
: hold the value from the previous reducer call. On first call, it contains the value you set to theinitial value
parameter of thereduce
method or, if you didn't supply an initial value,previousValue
shall hold the value of your array's first element (arr[0]
).currentValue
: hold the currentreduce
iteration's item.
Now, let's get back to the task we have, we need to calculate the number of persons who are still in the bus based on a supplied multidimensional array. Each item in that multidimensional array is an array of two values where the result we need at the end is: the sum of the differences between each array, in the multidimensional array, first and second values (sum = multiDim[i][0] - multiDim[i][1] multiDim[i 1][0] multiDim[i 1][1]
etc...).
To solve this task, we'll reduce
that multidimensional array into a single number (let's call it result
) by using a simple reducer function that will start by an initial value of 0
(as we're calculating a sum in our case) and will add, to the result
, the difference between the first and the second values of the array supplied by the reduce
at each iteration.
To illustrate, here's a live demo:
/**
* a function that calculates and returns the number of person who are still in the bus or precisely, the sum of the differences between "c[0]" and "c[1]"
* busArray: the supplied multidimensional array to reduce
* the reducer accepts two parameters:
* r: the result from the last call to the reducer function (initially set to 0, the initial value (see second parameter passed to the "reduce" method))
c: hold the current iteration's array.
*/
const calculateWhoAreInTheBus = busArray => busArray.reduce((r, c) => r = c[0] - c[1], 0);
/** test the created "calculateWhoAreInTheBus" function */
console.log(calculateWhoAreInTheBus([
[10, 0],
[3, 5],
[5, 8]
])); // should print: 5
console.log(calculateWhoAreInTheBus([
[3, 0],
[9, 1],
[4, 10],
[12, 2],
[6, 1],
[7, 10]
])); // should print: 17
console.log(calculateWhoAreInTheBus([
[3, 0],
[9, 1],
[4, 8],
[12, 2],
[6, 1],
[7, 8]
])); // should print: 21
console.log(calculateWhoAreInTheBus([
[0, 0],
[0, 0]
])); // should print: 0
CodePudding user response:
I would advice you to use Array.prototype.reduce instead. For example like this:
const reducer = (previous, current) => previous current[0] - current[1];
const answer = busStops.reduce(reducer, 0);
It is very brief (although this is not a goal in and of itself) and the reducer function does almost trivial work, so it does not complicate unneccesarily. Best of all it encapsulates the functionality with a minimal need of extra variables.
Othwerwise you could simplify your function a bit but use the let
keyword to keep variables locked to scope like:
function number(busStops) {
let answer = 0;
for (let bs of busStops) {
answer = bs[0] - bs[1];
}
return answer;
}