I start learning Javascript since a week and I try to do some practice about the loop,
So I try to make a function which each time I call it, I doubled the numbers in an array.
I manage to do it with the classic "for" loop like this as an example:
var numbers = [2, 5, 37, 500, 75];
function getDoubled() {
for (var i = 0; i < numbers.length; i++) {
(numbers[i] = numbers[i] * 2);
}
}
So here the numbers in my array doubled each time I call the function getDoubled(); and now I try to do the same with forEach method.
var numbers = [2, 5, 37, 500, 75];
function getDoubled(array) {
array.forEach(function(number) {
(number = number * 2);
})
}
But I wasn't able to change the array when I call the function getDoubled(numbers), however if I test with console.log(number*2), it worked in the console, so I wasn't able to figure it out the mistake.
Reassigning an identifier has no side-effects. That is, doing someVariable = somethingNew will only result in a discernable change in how your script runs if something else references the someVariable which has the new value in it. Here, the number = number * 2 does nothing because nothing is referencing the doubled number variable; reassigning the parameter doesn't do anything to the array.
The way to do this with forEach would be to reassign the index in the array, just like in the for loop.
var numbers = [2,5,37,500,75];
function getDoubled(array) {
array.forEach(function(number, i){
array[i] = number * 2;
})
}
getDoubled(numbers);
console.log(numbers);
Alternatively, a nicer approach would be to construct a new array with the changed values, which can be done with .map, which creates a new array by performing a callback on every element of the original array - that way you don't have to look at the (unimportant) indicies to get the output you want.
var numbers = [2,5,37,500,75];
function getDoubled(array) {
return array.map(num => num * 2);
}
console.log(getDoubled(numbers));
Related
I am trying to extend the Array class to add a Sum method to it. This is my code below, what am I doing wrong?
Class tipArray extends Array{
sum(values) {
for(i in values) {
total +=i;
}
}
}
var testArray = new tipArray();
testArray = [1,2,3,4];
console.log(testArray.sum());
Expected output = 10
Start by imagining how you would sum an array (maybe something with reduce).
Turn that into a function.
Add that as a method on your class. You can use this to refer to the array.
(optional) ask yourself if you really need a subclass instead of a function that accepts an array.
class tipArray extends Array{
sum() {
// Consider making sure the array contains items where sum makes sense here.
return this.reduce((sum, current) => sum + current)
}
}
var testArray = new tipArray(1,2,3,4);
console.log(testArray.sum());
// add another element and take another sum
testArray.push(10)
console.log(testArray.sum());
class tipArray extends Array {
sum() {
let val = 0;
for (let i = 0; i < this.length; i++) {
val += this[i];
}
return val;
}
}
var testArray = new tipArray(1, 2, 3, 4);
console.log(testArray.sum());
console.log(testArray.length);
Inside of the sum method, you refer to the array via this.
This seems to me more like asking for the solution of a homework after doing half the research on how to code in JavaScript.
Keywords, like class in JavaScript needs to be lowercase.
You didn't declare any of the variables. For example in the for loop you keep adding i to total, but what was the initial value of total? Declare the total variable before the for loop as let total = 0
The loop index i also needs to be declared as for (let i in values) {
The sum function doesn't return anything as you don't have any return statements. In this case JavaScript returns undefined and that is what you see in your console log. Add return total after your for loop so that the function would return something.
No need to use reduce here or extending array prototype as the issue isn't because for loop not being suitable to calculate sums.
You create a new instance of your own array class only to override it with a simple array at the next line with testArray = [1,2,3,4], as that line is the same as testArray = new Array(1, 2, 3, 4);. Write either var testArray = new tipArray(1, 2, 3, 4) or testArray.push(1, 2, 3, 4).
In essence the solution should be what Geuis wrote.
I've been trying to learn Javascript for the longest time, and it is kind of frustrating. I'm back to learning the basics again, and I was playing around with these for loops and arrays below.
Can someone please explain why the output of this code is [1,2,3,4,5] and not [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]?
var game1 = new Array();
for(i = 25; i > "love is like a river".length; i = i - 1) {
console.log(game1.push(i));
}
console.log(game1.push(i));
What this statement does is it prints to the console the index of the element being pushed. The result 1,2,3,4,5 is the length of the array.
What you want to code is:
var game1 = [];
for(i = 25; i > "love is like a river".length; i--){
console.log(i);
game1.push(i);
}
in the above example I switched the declaration of the array, because this is the most common way(this is not necessary).It will still work normally with your version of declaration. In the for loop I've switched
i = i - 1;
to shorthand version:
i-- or --i
which decrements ' i ' by 1. Also I've separated
console.log(i) and game1.push(i) to be separate
this will print out the result of ' i ' : 25,24,23,22,21
this is because the for loop does the action that the users defines at the end of the loop, so when the loop prints out 21 and pushes it to the array, it decrements to 20, at which the loop stops. The array will still have the numbers 25,24,23,22,21. but the console will not log it.
if you want the output you defined above you would have to:
var game1 = [];
for(i = 6;i >= 25; i++){
game1.push(i);
console.log(game1[i-6]);
}
in this you add ' i ' to game1 resulting in [6,7,8,9,10,11,12,13,14...25] and you log the variable at the index of ' i - 6'. This will result in the number int he square brackets being "0,1,2,3,4,5" starting at 0 because that is where all arrays indexs start at.
The length property returns the length of a string (number of characters). In this way "love is like a river".length gives 20. I think you mistook it as no. of words. The loop will then behave like
var game1 = new Array();
for(i = 25;i>20;i=i-1){
console.log(game1.push(i));
}
To get your expected answer the code would be:
var game1 = new Array();
for(i = 25;i>"love is like a river".length;i=i-1){
console.log(game1.push(i));
}
You are getting the expected [25, 24, 23, 22, 21] as the result for game1!
The 1, 2, 3, … you are seeing are the results of the Array push calls that you are logging, which yield the length of the array each time.
The "love is like a river".length is 20. So the loop is equivalent to this:
for(i = 25; i>20; i=i-1){
}
That being said, you have 5 calls of the console.log passing to it the following arguments one at each for step:
game1.push(25)
game1.push(24)
game1.push(23)
game1.push(22)
game1.push(21)
Not knowing exactly what game1.push does, it's hard to tell. However, supposing that game1 is an array, you would get at each push the new length of the array.
According to MDN:
The push() method adds one or more elements to the end of an array and
returns the new length of the array.
"love is like a river".length is 20, so you will start from i=25 until i=21.
[1,2,3,4,5] represents the length of game1 for each loop.
To see the game1 value:
for(i=0; i<game1.length; i++) {
console.log(game1[i]);
}
Result: [25,24,23,22,21]
Lets start by breaking down your code, beginning with the new Array() constructor that you stored in the variable game1.
var game1 = new Array();
At this point, all you have is an empty array, which has been stored in a variable to be used at a later time. Incidentally, this is the equivalent of the array literal: var game1 = [].
Lets step through to the next portion of your code, which is a for() loop:
for (i = 25; i > "love is like a river".length; i--) {}
This loop initializes at the upper bound of 25 and decrements down to a lower bound bound of 20 which is set by the length() property condition of the string. Within this loop you have the statement:
console.log(game1.push(i));
The method push() adds an element or elements to the end of an array and returns the new length of the array to the stack. This method relies on the length property to determine its injection point. So, before the iteration, the game1 stack is currently at 0 since you never populated the array with any values. As you perform the iteration, push() method will add to the stack an undefined value on each step, there by increasing the array length by 1.
This can be illustrated by calling your game1 variable with a single numeric argument, which will set the initial size of the array. Here is an example:
var string = 'love is like a river';
var game1 = new Array(15);
for (i = 25; i > string.length; i--) {
console.log(game1.push(1));
}
As you can see, I passed the numeric argument 15 to the new Array() constructor which set the initial game1 length stack to 15. Since we are decrementing from 25 (i = 25) to 20 (string.length) we iterate 5 times, producing the expected result: [16, 17, 18, 19, 20].
If you are looking for an outcome of [6, 7, 8,...,25] you can can adjust your for() loop incrementing as opposed to decrementing and set the intitializer to 6. Here is what it will look like:
var s = "love is like a river";
for (i = 6; i <= s.length + 5; i++) {
console.log(i);
}
I hope this is not a repeated question-- though I couldn't find much help on this.
I am practicing recursive functions (I'm a newbie), and I'm trying to multiply each number in an array. Sort of like a factorial. I have this code, but it is only returning undefined as a result.
Here is the code:
var stack = [];
function countDown(int) {
stack.push(int);
if (int === 1) {
return 1;
}
return countDown(int - 1);
}
function multiplyEach() {
// Remove the last value of the stack
// and assign it to the variable int
int = stack.pop();
x = stack.length;
// Base case
if ( x === 0 ) {
return;
}
// Recursive case
else {
stack[int - 1] = int * stack[x - 1];
return multiplyEach(int);
}
}
// Call the function countDown(7)
countDown(7);
// And then print out the value returned by multiplyEach()
console.log(multiplyEach());
Thank you so much for any insight.
Cheers!
The first thing to address is that your multiplyEach() function should have a parameter named int, from the looks of it. The approach you're using might be better suited to a different technique, but we'll get to that.
Next, in multiplyEach(), there are two possible paths:
The stack still has elements, in which case we multiply the new top value on the stack by the old one and move on to another run of multiplyEach.
The stack is empty, and we just return.
The problem here is that we aren't actually returning the final stack value, or leaving it on there to access later. We've effectively lost it, so what is the function outputting?
In many languages, we would have defined a return type for this function, either void for no value, or int for returning the multiplied value. However, in Javascript, there is no such thing as a function that doesn't return a value; "nothing" in JS is represented as undefined. When you return multiplyEach(), you're pushing another call of it onto the call stack, and waiting for an actual return value... which ends up being return;, which JS interprets as return undefined;. Again, in most languages, there would be some form of error, but not in JS! Let's look at two possible implementations:
The custom stack you use:
// your stack is fine, so we'll skip to the meat
function multiplyEach() {
var int = stack.pop(), x = stack.length;
stack[x - 1] *= int;
if(x < 2) // to multiply, we need at least two numbers left
return;
multiplyEach();
}
//...
multiplyEach();
console.log(stack[0]);
With a parameter, and using a list:
function multiplyEach(index) {
var int = list[index];
if(index == 0)
return int;
return int * multiplyEach(index - 1);
}
//...
console.log(multiplyEach(list.length - 1));
They're both different ways of implementing this recursively; all recursion inherently requires is for a function to call itself. Another possibility would have been having a parameter store the total, instead of multiplying the return values like in option 2; that's called tail recursion.
EDIT: noticed the base case for option 1 was in the wrong place, so I moved it. It should work now.
Recursively you can do this way:
function multiplyEach(arr, size) {
return size === 0 ? arr[size] : arr[size] * multiplyEach(arr, size - 1);
}
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(multiplyEach(array, array.length - 1));
But you can do it using the native method reduce, then you could do simply this:
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9].reduce(function(a, b) { return a * b; }));
ES6 version:
console.log([1, 2, 3, 4, 5, 6, 7, 8, 9].reduce((a, b) => a * b));
I hope it helps.
There are times recursion is better suited to solve a problem and there are times iteration is better suited to solve a problem.
Recursion is better suited for performing an action until a condition is met then exiting, similar to a while loop.
Iteration is better suited for performing an action N number of times then exiting, similar to a for loop.
In our case, we want to input an array and output the product of all elements of that array. In other word, we want to perform N - 1 multiplications where N is the number of elements in the array. Since we know the number of operations we want to perform we should solve our problem with iteration which is done below.
var arr = [1, 2, 3]
var result = multiplyEach(arr)
console.log(result)
// -> 6
function multiplyEach(arr) {
var result = 1
arr.map(function(value) {
result *= value
})
return result
}
Keep in mind though that the above is an approximate rule of thumb because sometimes recursion will be a more elegant solution than iteration. Here's the simple, recursive, and elegant implementation of the real factorial.
function factorial(value) {
return 1 === value ? 1 : value * factorial(value - 1)
}
The iterative implementation of factorial is not as pretty in while loop form nor for loop form.
function factorial(value) {
var result = 1
while (value > 0) {
result *= value
value--
}
return result
}
function factorial(value) {
var result = 1
for (var i = 0; i < value; i++) {
result *= value
}
return result
}
I think the main issue is that you do not have an argument in the multiplyEach() definition, but you attempt to call it with one inside the function.
Something like this works:
var stack = [1, 2, 3, 4, 5, 6, 7];
function multiplyEach(arr) {
if (arr.length == 0) {
return 1;
} else {
return arr.pop() * multiplyEach(arr);
}
}
console.log(multiplyEach(stack));
The base case in the recursive function multiplyEach() returns undefined.
That's where your problem lies.
A simple fix would be:
var stack = [];
var multipliedStack = [];
function countDown(int) {
stack.push(int);
if (int === 1) {
return 1;
}
return countDown(int - 1);
}
function multiplyEach() {
// Remove the last value of the stack
// and assign it to the variable int
int = stack.pop();
x = stack.length;
// Base case
if ( x === 0 ) {
return multipliedStack.reverse();
}
// Recursive case
else {
multipliedStack.push(int * stack[x - 1]);
return multiplyEach(int);
}
}
// Call the function countDown(7)
countDown(7);
// And then print out the value returned by multiplyEach()
console.log(multiplyEach());
I don't fully get what you mean by "sort of like a factorial"? What exactly is the function supposed to do?
To understand recursion you need to wrap your head around what a recursive base case is and also I think you need to revise push() and pop() which are not used in a proper way in your code.
Recursive functions are usually abit confusing if you are used to iteration, keep trying and you'll get comfortable with it rather quick.
I'm a complete newbie to programming and mathematical concepts (took Math 101 in college) so I'm struggling with this problem:
Write a function that takes in a number, and returns an array with that number in it that many times.
Here's the code I've got so far:
function numReturn(x) {
var newArray = [];
if (typeof x === "number") {
return newArray.push[x]* x;
} else {
return null;
}
}
Here's my thought process:
Create a function that can take in a number, x.
Within that function, create a blank array so you can push values to it later.
Check if the typeof value entered in for x is a number. If it is, return it pushed to the end of the blank array. Otherwise, return null.
When I put this in the Javascript console and plug a value in, it comes back undefined. Anyone have some pointers for me?
function a(i) {
var a = new Array(i);
return a.fill(i);
}
or return new Array(i).fill(i);, for short. Test:
a(4)
// --> [4, 4, 4, 4]
Array.prototype.fill() is an ES6 method and is not yet universally implemented. Chrome and Firefox have it, IE does not - but there is a polyfill available.
Compare: http://kangax.github.io/compat-table/es6/#test-Array.prototype_methods_Array.prototype.fill
In order to do something an arbitrary number of times, one uses a loop. There are several loops, but here the for loop is most appropriate.
A for loop has the following structure:
for(var i = 0; i < x; i++) {
// ^initializer
// ^condition
// ^increment
//body
}
The initializer is the first thing that is done when entering the loop. IN this case, it means a variable named i is set to 0. Then the condition x is checked. If the condition i < x holds, the loop is executed: the body is executed. After the body is executed, the increment is performed (here i++), and then the condition is rechecked, if the condition still holds, the loop is executed again, and so on.
You can apply this concept as follows:
function numReturn(x) {
var newArray = [];
if (typeof x === "number") {
for(var i = 0; i < x; i++) {
newArray.push(x);
}
return newArray;
} else {
return null;
}
}
This: newArray.push[x]* x does not push x times. The * operator just multiplies numbers, always and only. You want to push x times, so use a for like this:
for (var i = 0; i < x; i++ )
newArray.push(x);
and then return newArray.
Taking from answer of Most efficient way to create a zero filled JavaScript array?
function numReturn(x){
return Array.apply(null, Array(x)).map(Number.prototype.valueOf,x);
}
console.log(numReturn(10)); // [10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
var n = 7
var result = Array.apply(null, {length: n}).map(function(){return n})
// Demo output
document.write(JSON.stringify(result))
As function:
function numReturn(x) {
if (typeof x === "number") {
return Array.apply(null, {length: n}).map(function(){return n})
} else {
return null;
}
}
I have an issue with Javascript. I want to make the program , which generates 6 random numbers ( from 1 to 49 ).Anyway im doing it with for loop and it works. But when I try to find if any of those 6 numbers has a duplicate number , to replace it with a new random number. I've looked at js array duplicate functions , Im applying it , but it seems my fault is in the logic , still beginner with js , so please help me :)
js code:
var arr = new Array(7);
var numbers = [];
for(var i=1; i<arr.length;i++){
numbers[i] = Math.floor(Math.random()*48)+1;
if(numbers[i] == numbers[i+1]){
arr.indexOf(numbers[i]);
arr.push(Math.floor(Math.random()*48));
}
}
i`m trying to apply indexOf ( to find the duplicate number's index, and after that to replace it with new element via push()). Please give me some advises how to improve on my programming logic skills :(
First, JavaScript arrays are zero-indexed, so the first index is 0, not 1. Although it is valid to skip the first index and use the second to seventh indices instead, you will usually want to avoid that.
Second, why do you check numbers[i] against numbers[i + 1]? At that point, numbers[i + 1] won't have been set yet as it will be set in the next iteration. Additionally, even if this problem did not exist, your code would fail to catch this sequence: [ 5, 3, 5 ].
Third, I am not quite sure why you use two different arrays. Although you definitely can, there is no good reason to do so.
I will suggest another way to solve your problem and add comments to the steps necessary. I hope these will help you to understand this solution to your problem.
// Create an array for the chosen numbers
var numbers = [];
// Loop to generate 6 elements, zero-based
for(var i = 0; i < 6; i++) {
// This variable will hold the number we choose
var number;
// This is a do-while loop which generates a random integer
do {
// Generate a random integer between 1 and 49 (incl.)
number = Math.floor(Math.random() * 48) + 1;
} while(numbers.indexOf(number) != -1); // Exit loop once the number is not contained in the array
// Store the number in the array
numbers[i] = number;
}
This algorithm is short (8 SLOC) and pretty efficient.
This is one way you could do it:
var numbers = [];
for(i=0;i<6;i++){
numbers[i] = Math.floor(Math.random()*48)+1;
//this loop will help us check all of the already assigned numbers.
for(x=0;x<i;x++){
if(numbers[x] == numbers[i]){
i--;
}
}
}
This might not be the most efficient and optimal way to do it, but it sure works and it will give you no repetition on the numbers now that it will loop untill it finds a different number. Its a fast and short solution, yet not the most efficient. Hope this helps =).
for (var a=[],i=1;i<40;++i) a[i]=i;
function shuffle(array) {
var tmp, current, top = array.length;
if(top) while(--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
a = shuffle(a);
Random Numbers , No repeats
This statement will never be true:
if(numbers[i] == numbers[i+1]){
When you start, numbers array is empty. Then you assign one random to element 0. Then you try to compare element 0 in numbers to 1, but numbers[1] will be undefined.
The best way to do this is to start with an empty arr array, meaning length of 0. Loop until length equals 6. In the loop, generate a random number and only push the value into the arr array if the number doesn't exist in there.
UPDATE:
After seeing some of the answers, I think this is probably the simplest:
var arr = [],
num;
while (arr.length < 6) {
num = Math.floor(Math.random() * 48) + 1;
if (arr.indexOf(num) === -1) {
arr.push(num);
}
}
console.log(arr);