Javascript forEach Loop - javascript

Trying to make this function true. I think the problem is in my for loop.
function forEach(array, callback){
console.log(array, callback);
for(var i = 0; i < array.length; i++) {
}
}
// testing your code with console.assert
var total = 1;
var myArray = [1, 2, 3, 4];
function multiplyTotal(a) {
total *= a;
}
forEach(myArray, multiplyTotal);
// and finally assert; if this fails, the program stops
console.assert(total === 24);

function forEach(array, callback){
console.log(array, callback);
for(var i = 0; i < array.length; i++) {
callback(array[i]); // you need to call callback function
}
}

Additionally, Javascript already has a built in function for this:
myArray.forEach(multiplyTotal);
http://www.w3schools.com/jsref/jsref_forEach.asp

Related

Write a function which returns the sum of the values for each parameter it receives

I want the result to be the sum of every number, but instead, it only sums the first number with the rest. For example if the parameter were : 1,2,3,4,5
it should come out with 15 but instead, it became 3456. Where did i go wrong?
Thank u guys, i m new to this and thing were really complicated :((
function func1(sum) {
var result = '';
var i;
for (i = 1; i < arguments.length; i++) {
result += arguments[i] + sum;
}
return result;
}
Start with result being a number, not a string: var result = 0.
If you're iterating through arguments, you may as well skip the named first argument altogether.
Start iterating from 0, not 1.
function func1() {
var result = 0;
var i;
for (i = 0; i < arguments.length; i++) {
result += arguments[i];
}
return result;
}
console.log(func1(1, 2, 3, 4, 5));
This should work
function sum(value) {
let result = 0;
for(let i =0; i < value.length; i++) {
result +=value[i];
}
return result
}
let arry = [1,2,3,4,5]
console.log(sum(arry)) //15

forEach does not mutate an array that I pass in

I've created a simple forEach function and I'm trying to understand why, when I run it with myArray, it doesn't mutate the array even though I run element*2.
function forEach(array, callback) {
for (var i = 0; i < array.length; i++) {
callback(array[i],i,array)
};
}
var myArray = [1,2,3]
forEach(myArray,function(element){element*2})
console.log(myArray)///[1,2,3]
You have to modify the array in the for loop, like this:
function forEach(array, callback) {
for (var i = 0; i < array.length; i++) {
array[i] = callback(array[i],i,array)
};
}
var myArray = [1,2,3]
forEach(myArray,function(element){return element*2})
console.log(myArray)
As we were discussing in the comments, the best way would be to implement something like the map function: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
function map(array, callback) {
var out = [];
for (var i = 0; i < array.length; i++) {
out.push(callback(array[i],i,array))
};
return out;
}
var myArray = [1,2,3]
var myOtherArray = map(myArray,function(element){return element*2})
console.log(myArray)
console.log(myOtherArray)
This way myArray is not touched, you create a new one. This is usually the best option, but sometimes you may want to modify it in place, because it is huge or for some other (good?) reason. In that case you can use the first option.
You should assign new array element value, because primitive types (like numbers in your case) are immutable, so element * 2 does not modify element.
To do the job, you should not touch you current forEach implementation, because forEach is not supposed to return values from callback (this is not map). In this case you should do something like this:
function forEach(array, callback) {
for (var i = 0; i < array.length; i++) {
callback(array[i], i, array);
}
}
var myArray = [1,2,3];
forEach(myArray, function(element, i, arr) {
arr[i] = element * 2;
});
document.write(JSON.stringify( myArray ));
This should work, explicitly assigning the variable.
function forEach(array, callback) {
for (var i = 0; i < array.length; i++) {
array[i] = callback(array[i])
};
}
var myArray = [1,2,3]
forEach(myArray,function(element){return element*2})
console.log(myArray)///[1,2,3]
Yep, bad answer. This [snippet] would do it though.
Anyway, in modern browsers we have Array.forEach to availability
function foreach(array, callback) {
for (var i = 0; i < array.length; i++) {
array[i] = callback(array[i]);
// ^ assign the new value (from the callback function)
};
}
var myArray = [1,2,3]
foreach( myArray, function (element){ return element * 2 } );
// ^ return the new value
document.querySelector('#result').textContent = myArray;
<pre id="result"></pre>

Function with for loop - game dice

I create this function in order to have a random number for my first dice game.
function rollDice() {
return Math.floor(Math.random()*6 + 1);
}
Now I want create a new function dices() with a for loop in order to use how much dices the user need.
Usually I used length in a loop as this example:
for (var i=1; i < dices.length; i++) {
// do something
}
How you got any suggestions on how to fix this?
Thank you!
I don't know if it's really what you're looking for, but you can simply create a function and replace dice.length by the number of time you want to roll, see this example:
function rollManyDice(number) {
var diceNumber = 0;
for (var i = 0; i < number; i++) {
diceNumber += rollDice();
}
return diceNumber;
}
Something like this function if I understand your question? It returns an array with the results from the number of dices thrown.
function throwDice(num) {
var arr = [];
for (var i = 0, l = num; i < l ; i++) {
arr.push(rolldice());
}
return arr;
}
throwDice(3); // e.g. [3, 5, 1]
function rollDice(sides, amount){
var results = [];
for (var i=0; i < amount; i++){
results.push( Math.floor(Math.random()*sides + 1) );
}
return results;
}
should return a array of how ever amount of dice with the specified number of sides.

Workaround for let keyword?

How can I get this
var i = 0;
var codes = [1, 2, 3];
for (var i = 0; i < codes.length; ++i)
{
setTimeout(function(){alert(codes[i]);},100);
}
To alert 1, 2 and 3 without using let keyword?
or bind an event on an element (example):
var i = 0;
var codes = [1, 2, 3];
for (var i = 0; i < codes.length; ++i)
{
$("div").eq(i).click(function(){
alert( codes[i] );
});
}
Use a self-executing anonymous function and pass in i as an argument for variable closure.
var i = 0;
var codes = [1, 2, 3];
for (var i = 0; i < codes.length; ++i)
{
(function( index ) {
setTimeout(function(){alert(codes[index]);},100);
})(i);
}
Here's an example.
You need to make use of a closure. I typically create a "generator" function that returns a function which is defined in the desired context:
var i = 0;
var codes = [1, 2, 3];
function callbackGenerator(i) {
return function(){alert(codes[i]);}
}
for (var i = 0; i < codes.length; ++i)
{
setTimeout(callbackGenerator(i), 100);
}
More info and good examples here:
https://developer.mozilla.org/en/JavaScript/Guide/Closures
var i = 0;
var codes = [1, 2, 3];
var timeoutFunc = function() {
alert(codes[i++]);
if (i < codes.length) {
setTimeout(timeoutFunc, 100);
}
};
setTimeout(timeoutFunc, 100);
This should do it.
var codes = [1, 2, 3];
for (var i = 0; i < codes.length; ++i)
setTimeout(function(code){return function(){
alert(code);
}}(codes[i]), 100);
Use a self-executing function:
for (var i = 0; i < codes.length; ++i) (function(bound_i) {
setTimeout(function(){alert(codes[bound_i]);},100);
})(i);
Optionally using a var statement for more verbose code:
for (var i = 0; i < codes.length; ++i) (function() {
var bound_i = i;
setTimeout(function(){alert(codes[bound_i]);},100);
})();
Or use a named function instead if you want to:
function foo(i) {
setTimeout(function(){alert(codes[i]);},100);
}
for (var i = 0; i < codes.length; ++i) {
foo(i);
}
Either example forms a closure, which introduces new variable scope. Alternatively, ES5 has Function.bind that could be used on the anonymous function, but it is not universally supported in all browsers yet. (I'm thinking of IE.)

Javascript slice.call(arguments) and recursion

I have a simple recursive javascript function that can be called with additional arguments:
AllDataRows(grid.Rows, process);
AllDataRows(grid.Rows, process, storeIDs);
The problem is that if the function has to call itself then any additional arguments are lost. I tried using Array.prototype.slice.call(arguments, 2) to pass the arguments along, but they end up as one element arrays. The cb function then fails because it isn't expecting an array (it would be a hidden textbox).
How can I resolve this?
Thanks
function AllDataRows(rowList, cb) {
if (rowList.getRow(0).GroupByRow) {
for (var i = 0; i < rowList.length; i++)
AllDataRows(rowList.getRow(i).Rows, cb);
} else {
var args = Array.prototype.slice.call(arguments, 2);
for (var j = 0; j < rowList.length; j++)
cb.apply(rowList.getRow(j), args);
}
}
function AllDataRows(rowList, cb) {
if (rowList.getRow(0).GroupByRow) {
for (var i = 0; i < rowList.length; i++) {
var aa = Array.prototype.slice.call(arguments, 0);
aa[0] = rowList.getRow(1).Rows;
AllDataRows.apply(this, aa);
}
} else {
var args = Array.prototype.slice.call(arguments, 2);
for (var j = 0; j < rowList.length; j++)
cb.apply(rowList.getRow(j), args);
}
}
Just use apply when you make the recursive call, fixing up the argument array to account for the sub-group you're opening up.

Categories

Resources