Trouble pushing to an array in JS - javascript

Below is just a section of my code but I know it's problematic because I can't get it to return any value except 'undefined'. I have been over this for hours and cannot figure it out.
I want to be able to input a number and have its factors pushed to an array. I have tested it by alerting the first item in the array and I get nothing. I'm sure this is a pretty easy but I just can't figure it out. Here is the code:
var numberInQuestion = prompt("Of what number are you wanting to find the largest prime factor?");
//determine factors and push to array for later use
var factorsArray = [];
function factors(numberInQuestion){
for(var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0){
return factorsArray.push[i];
} else {
continue;
}
}
};
factors(numberInQuestion);
alert(factorsArray[0]);
Thanks for any help!

you can only return one value
you must use (), not [] for calling push
factorsArray should be local to factors (put the definition inside the function)
the else { continue; } is useless
Here is the fully corrected code:
var numberInQuestion = prompt("Of what number are you wanting to find the factors of?");
//determine factors
function factors(numberInQuestion){
var factorsArray = []; // make it local
for (var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0){
factorsArray.push(i); // use (), and don't return here
} // no need for else { continue; } because it's a loop anyway
}
return factorsArray; // return at the end
};
var result = factors(numberInQuestion); // assign the result to a variable
alert(result);
Here's a JSFiddle.

You have an error in your pushing syntax. Correct syntax for pushing is -
factorsArray.push(i);
Also returning immediately from the function after finding the first divisor will not give you the full list. You probably want to return after you've found out all the divisors.
Taking all of the above into consideration, you should rewrite your function as follow -
function factors(numberInQuestion){
for(var i = 2; i < numberInQuestion - 1; i++){
if(numberInQuestion % i === 0) {
factorsArray.push(i);
}
}
}
and you will be OK.

You've coded this so that when you find the first factor your function returns immediately. Just get rid of the return keyword in that statement. (What "return" means in JavaScript and other similar languages is to immediately exit the function and resume from where the function was called.)
Oh, also, you call functions (like .push()) with parentheses, not square brackets.

The function should not return when pushing to the array. Return the array after executing the loop. The else clause is also unnecessary.
var numberInQuestion = prompt("Of what number are you wanting to find the largest prime factor?");
function factors(numberInQuestion){
var factorsArray = [];
for(var i = 2; i < numberInQuestion-1; i++){
if(numberInQuestion % i === 0 && isPrime(i)){
factorsArray.push(i);
}
}
return factorsArray;
};
var factors = factors(numberInQuestion);
alert(factors[factors.length-1]);
//From: http://stackoverflow.com/questions/11966520/how-to-find-prime-numbers
function isPrime (n)
{
if (n < 2) return false;
var q = Math.sqrt (n);
for (var i = 2; i <= q; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
Given the purpose of the example two items must be considered
The code does not determine if the number is actually prime. The code will return the smallest factor possible since the loop starts at two and increments, then returns the first element in the array. The largest factor would actually be the last element in the array. I have corrected the example to find the greatest prime factor. You can test it via this fiddle: http://jsfiddle.net/whKGB/1/

Related

Explanation How Rectangle Recursion JavaScript works

I am a beginner in code world. I have troubles understanding recursion in JavaScript especially when it needs two or more looping. Like I want to print rectangle using recursion. I don't know completely how to make a base case, condition when it still executed. For examples, these codes below I use to print rectangle or holey rectangle.
function box(num) {
for (let i = 0; i < num; i++) {
let str = ''
for (let j = 0; j < num; j++) {
str += '*'
}
console.log(str)
}
}
box(5)
function holeBox (num) {
for(let i = 0; i < num; i++){
let str = ''
for(let j = 0; j < num; j++){
if(i == 0 || i == num -1 || j == 0 || j == num - 1) {
str += '*'
} else {
str += ' '
}
}
console.log(str)
}
}
holeBox (5)
Please help me to understand recursion, an explanation would be great. My goals are not only to solve those codes but also to understand how recursion works. I've searched there's no good source to learn recursion, or I just too dumb to understand. Thanks in advance
To understand how recursion works, just think of how you can split up what you want to accomplish into smaller tasks, and how the function can complete one of those tasks, and then call itself to do the next- and so on until it is finished. I personally don't think printing boxes is the best way to learn recursion, so imagine you wanted to search an array for a specific value; ignore JavaScript's indexOf()/find() functions or similar for now.
To do this using loops, its easy, just iterate over the array, and check every value:
//Returns the index of the first occurrence of a value in an array, or -1 if nothing is found
function search(needle, haystack) {
for (let i = 0; i < haystack.length; i++) {
if (haystack[i] == needle) return i;
}
return -1;
}
Doing this using recursion is easy as well:
function recursiveSearch(needle, haystack, i) {
if (i > (haystack.length - 1)) return -1; //check if we are at the end of the array
if (haystack[i] == needle) return i; //check if we've found what we're looking for
//if we haven't found the value yet and we're not at the end of the array, call this function to look at the next element
return recursiveSearch(needle, haystack, i + 1);
}
These functions do the same thing, just differently. In the recursive function, the two if statements are the base cases. The function:
Tests if the current element is out of bounds of the array (meaning we've already searched every element), and if so, returns -1
Tests if the current element is what we're looking for, and if so, returns the index
If neither of the statements above apply, we call this function recursively to check the next element
Repeat this until one of the base cases kicks in.
Note that recursive functions are usually called from other helper functions so that you don't have to pass the initial parameters to call the function. For example, the recursiveSearch() function above would be private, and it would be called by another function like this:
function search(needle, haystack) {
return recursiveSearch(needle, haystack, 0);
}
so that we don't have to include the third parameter when we call it, thus decreasing confusion.
Yes, even your box code can be turn into recursion but I don't think it will help you understand the concept of recursion.
If you really have to:
function getBox(arr, size) {
let length = arr.length;
if (length == size)
return arr; // recursion stop rule - if the size reached
for (let i = 0; i < length; i++)
arr[i].push("*"); // fill new size for all row
arr.push(new Array(length + 1).fill("*")); // add new row
return getBox(arr, size); // recursive call with arr bigger in 1 row
}
However, I believe #Gumbo answer explain the concept better then this...

JS create an array with unique random numbers

Full code looks like this, ideally we have 4 div boxes that need to be randomly filled with random numbers ansValue, one of them (rightAnsValue with its rightAnsId) is already done and works fine, I've managed to make it unique in comparison to others (code without commented section). But met a problem with making others unique, I keep having some identical values in my boxes. In comments is one way I tried to solve this, but pretty sure there is a much simpler and smarter solution that actually works. I would appreciate if you could help to find an understandable solution to this problem.
(P.S. I've seen similar questions but they are either too dificult or done without JS.)
function createAnswers(){
for(ansId=1; ansId<5; ansId++){
if(ansId!=rightAnsId){
for(i=1; i<10; i++){
digitArray[i-1] = i;
}
genNewRandNum();
// ansArray.length = 3;
// ansArray.push(ansValue);
// for(k=0; k<3; k++){
// if(ansArray[k] == ansArray[k+1] || ansArray[k] == ansArray[k+2]){
// genNewRandNum();
// ansArray[k] = ansValue;
// }else if(ansArray[k+1] == ansArray[k+2]){
// genNewRandNum();
// ansArray[k+1] = ansValue;
// }else{
// break;
// }
// }
if(ansValue!=rightAnsValue){
document.getElementById("box" + ansId).innerHTML = ansValue;
}else{
genNewRandNum();
document.getElementById("box" + ansId).innerHTML = ansValue;
}
}
}
}
The way I generate new numbers:
function genNewRandNum(){
rand1 = digitArray[Math.floor(Math.random() * digitArray.length)];
rand2 = digitArray[Math.floor(Math.random() * digitArray.length)];
ansValue = rand1 * rand2;
}
Replace your genNewRandNum() with below code. I have used IIFE to create a closure variable alreadyGeneratedNumbers thats available inside the function generateRandomNumber() thats returned.
So everytime genNewRandNum() is executed, it checks against alreadyGeneratedNumbers to make sure it always returns a unique between 1 and 9.
var genNewRandNum = (function(){
var alreadyGeneratedNumbers = {};
return function generateRandomNumber() {
var min = Math.ceil(1),
max = Math.floor(9);
randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
if(alreadyGeneratedNumbers[randomNumber]) {
return generateRandomNumber();
} else {
alreadyGeneratedNumbers[randomNumber] = randomNumber;
return randomNumber;
}
}
})();
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
Note: If you call genNewRandNum() for the 10th time it will throw error. So if you have a use case where you would need to reset it after all numbers from 1 to 9 are returned, then you need to add code to handle that
The easiest way to brute-force this is to use accept/reject sampling. You can do something like so:
uniqueRandomNumbers = function(n, nextRandom)
{
var nums = {}; var m = 0;
while(m < n)
{
var r = nextRandom();
if(! nums.hasOwnProperty(r))
{
nums[r] = true; m++;
}
}
return Object.keys(nums);
}
Here I'm using the fact that js objects are implemented as hashmaps to get a hashset. (This has the downside of converting the numbers to strings, but if you're not planning on imediately doing arithmetic with them this is not a problem.)
In order to get four unique integers between 0 and 9 you can then do something like:
uniqueRandomNumbers(4, function() { return Math.floor(Math.random() * 10); })
If you want something a little better than brute force (which probably isn't relevant to your use case but could help someone googling this), one option is to go through each element and either take or leave it with an appropriate probability. This approach is outlined in the answers to this question.

How to find the missing next character in the array?

I have an array of characters like this:
['a','b','c','d','f']
['O','Q','R','S']
If we see that, there is one letter is missing from each of the arrays. First one has e missing and the second one has P missing. Care to be taken for the case of the character as well. So, if I have a huge Object which has all the letters in order, and check them for the next ones, and compare?
I am totally confused on what approach to follow! This is what I have got till now:
var chars = ("abcdefghijklmnopqrstuvwxyz"+"abcdefghijklmnopqrstuvwxyz".toUpperCase()).split("");
So this gives me with:
["a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z"]
Which is awesome. Now my question is, how do I like check for the missing character in the range? Some kind of forward lookup?
I tried something like this:
Find the indexOf starting value in the source array.
Compare it with each of them.
If the comparison failed, return the one from the original array?
I think that a much better way is to check for each element in your array if the next element is the next char:
function checkMissingChar(ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) == ar[i-1].charCodeAt(0)+1) {
// console.log('all good');
} else {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(checkMissingChar(a));
console.log(checkMissingChar(b));
Not that I start to check the array with the second item because I compare it to the item before (the first in the Array).
Forward Look-Ahead or Negative Look-Ahead: Well, my solution would be some kind of that. So, if you see this, what I would do is, I'll keep track of them using the Character's Code using charCodeAt, instead of the array.
function findMissingLetter(array) {
var ords = array.map(function (v) {
return v.charCodeAt(0);
});
var prevOrd = "p";
for (var i = 0; i < ords.length; i++) {
if (prevOrd == "p") {
prevOrd = ords[i];
continue;
}
if (prevOrd + 1 != ords[i]) {
return String.fromCharCode(ords[i] - 1);
}
prevOrd = ords[i];
}
}
console.log(findMissingLetter(['a','b','c','d','f']));
console.log(findMissingLetter(['O','Q','R','S']));
Since I come from a PHP background, I use some PHP related terms like ordinal, etc. In PHP, you can get the charCode using the ord().
As Dekel's answer is better than mine, I'll try to propose somewhat more better answer:
function findMissingLetter (ar) {
for (var i = 1; i < ar.length; i++) {
if (ar[i].charCodeAt(0) != ar[i-1].charCodeAt(0)+1) {
return String.fromCharCode(ar[i-1].charCodeAt(0)+1);
}
}
return true;
}
var a = ['a','b','c','d','f']
var b = ['O','Q','R','S']
console.log(findMissingLetter(a));
console.log(findMissingLetter(b));
Shorter and Sweet.

How to count vowels in a Javascript string with two functions?

I'm trying to write a Javascript function that counts the vowels in a string by calling another function inside that function, but when I test it in the console it returns 0.
Here is my first function that works fine and recognizes if a string is a vowel:
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
For the second function none of my ideas have worked. Here are a few examples of what I have tried so far:
This one returns me a 0:
function countVowels(str){
var count = 0;
for(var i; i <= str.length; ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I also tried the above, but removing the .length after str in the for() area.
Another example, but this one gives me an error:
function countVowels(str){
var count = 0
var pattern = /[aeiouAEIOU]/
for(var i = 1; i <= str.length(pattern); ++i){
if(isVowel(i)){
++count;
}
}
return count;
};
I've tried various other functions as well, but for the sake of keeping this post relatively short I won't continue to post them. I'm quite new to Javascript and I'm not sure what I'm doing wrong. Any help would be greatly appreciated!
Try using .match() with the g attribute on your String.
g: global
i: case insensitive
Regexp documentation
function countVowels(ch){
return ch.match(/[aeiouy]/gi).length;
}
var str = "My string";
alert(countVowels(str)); // 2
Although Robiseb answer is the way to go, I want to let you know why you code is not working (I'm referring your first attempt). Basically you made two mistakes in the loop:
As CBroe stated, you are passing i to your isVowel function. i is a integer representing the index of the loop, not the actual character inside the string. To get the character you can do str.substr(i, 1), what means "give me one character from the position i inside the string".
You are not giving a initial value to the i variable. When you create a variable, it is undefined, so you can not increment it.
alert(countVowels("hello"));
function countVowels(str) {
var count = 0;
for (var i = 0; i <= str.length; ++i) {
if (isVowel(str.substr(i, 1))) {
count++;
}
}
return count;
};
function isVowel(ch) {
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
};
UPDATE: You will see that other answers use other methods to select the character inside the string from the index. You actually have a bunch of different options. Just for reference:
str.slice(i,i+1);
str.substring(i,i+1);
str.substr(i,1));
str.charAt(i);
str[i];
i is the index, not the character. It should be:
if (isVowel(str[i])) {
count++;
}
Also, str.length(pattern) is wrong. length is a property, not a function, so it should just be str.length.
You forgot to assign the value 0 to i variable
And parameter for isVowel is the character, not the index of string
Here information about the JS language: https://stackoverflow.com/tags/javascript/info
function isVowel(ch){
var pattern = /[aeiouAEIOU]/
return pattern.test(ch);
}
function countVowels(str){
var count = 0;
// you forgot to assign the value to i variable
for(var i = 0; i < str.length; i++){
// isVowel(str[i]), not isVowel(i)
if(isVowel(str[i])){
count++;
}
}
return count;
}
console.log(countVowels('forgot'))
Obviously you should do it this way:
function isVowel(c){
var lc = c.toLowerCase();
if(lc === 'y'){
return (Math.floor(Math.random() * 2) == 0);
}
return ['a','e','i','o','u'].indexOf(lc) > -1;
}
function countVowels(s){
var i = 0;
s.split('').each(function(c){
if(isVowel(c)){
i++;
}
});
return i;
}
console.log(countVowels("the quick brown fox jumps over the lazy dog"));
Which, although less efficient and less useful than other answers, at least has the entertaining property of returning a different count 50% of the time, because sometimes Y.

how to create a loop in a function with another function?

I'm new to Java and I'm doing a uni course. I've been asked to design three functions.I have to find the difference between each adjacent numbers in an array, another to total the array and the last one to calculate the difference using the other functions then write a programme. I'm totally lost on the last function and my tutor has gone away on hols. Here is the code I have done so far. I don't want people doing the code for me but if anyone can advice me what I need to do I would appreciate your advice. I'm not sure how to loop the difference function into the array and store it into the new array I have made. If anyone could explain where I am going wrong I would love to hear from you!
var numberArray = [10,9,3,12];
// function difference will find the highest value of the two numbers,find the difference between them and return the value.
function difference(firstNumber, secondNumber)
{
if (firstNumber > secondNumber)
{
return (firstNumber - secondNumber);
}
else
{
return (secondNumber - firstNumber);
}
}
// function sum will add the total numbers in the array and return the sum of numbers.
function sum(numberArray)
{
numberTotal = 0
for (var total = 0; total < numberArray.length; total = total + 1)
{
numberTotal = numberTotal + numberArray[total]
}
{
return numberTotal
}
/*code the process that calculates a new array containing the differences between all the pairs
of adjacent numbers, using the difference() function you have already written.
This function should be named calculateDifferences() and should accept an array numberArray.
The function should first create a new empty array of the same size as numberArray
It should then calculate the differences between the pairs of adjacent numbers,
using the difference() function, and store them in the new array. Finally, the function should return the new array.
The calculation of the differences should be done in a loop, at each step finding the difference between each
array element and the next one along in the array, all except for the last difference,
which must be dealt with as a special case, because after the last element we have to wrap round to the start again.
So the final difference is between the last and first elements in the array.*/
function calculateDifferences()
var createArray = new Array (numberArray.length);
{
createArray = 0;
for (var c = 0; c < numberArray.length; c = c + 1)
{
createArray = difference(numberArray[c]);
}
{
return createArray
}
}
your implementation of function "calculateDifferences" is not correct.
this function should look like this:
function calculateDifferences()
{
var createArray = new Array (numberArray.length);
for (var c = 0; c < numberArray.length - 1 ; c = c + 1)
{
/*
because of the function "difference" has two parameters (firstNumber, secondNumber) in its declaration, we should give two arguments. (that are adjacent elements in array)
*/
createArray[c] = difference(numberArray[c],numberArray[c+1]);
}
/ *
calculating difference of first and last element of array and
assign it to returning array's last element.
*/
createArray[numberArray.length - 1] = difference(numberArray[0],numberArray[numberArray.length - 1]);
return createArray;
}
You should index createArray the same way you already do with numberArray[c].

Categories

Resources