I have a problem with the following task. I want to achieve this output for n = 5:
* 2 3 4 5
* * 3 4 5
* * * 4 5
* * * * 5
* * * * *
* * * * *
* * * * 5
* * * 4 5
* * 3 4 5
* 2 3 4 5
I'm stuck in the second part of the exercise. My code for now:
var n = 5;
var numbers = '';
for (var i = 1; i <= n; i++) {
numbers += i;
}
for (var i = 0; i < n; i++) {
numbers = numbers.replace(numbers[i], '*');
console.log(numbers);
}
So far I have this result:
*2345
**345
***45
****5
*****
So now I need to add the spaces between numbers/stars, and make a reverse loop. I have no idea how to do it.
In addition, there is probably a faster solution to this task than I did.
You can save each of the numbers you generate on a stack (an array), and then pop them from the stack in reverse order:
var n = 5;
var numbers = '';
var stack = []; // <--- add this
for (var i = 1; i <= n; i++) {
numbers += i + ' '; // add a space here
}
for (var i = 0; i < n; i++) {
numbers = numbers.replace(i, '*'); // find/replace the digit
console.log(numbers);
stack.push(numbers); // <--- push on stack
}
while (stack.length > 0) {
numbers = stack.pop(); // <--- pull in reverse order
console.log(numbers); // <--- and print
}
.as-console-wrapper { max-height: 100% !important; top: 0; }
A similar way, without the use of a stack, delays the output, and gathers all the strings in two longer strings which each will have multiple lines of output:
var n = 5;
var numbers = '';
var stack = [];
var output1 = ''; // <-- add this
var output2 = ''; //
for (var i = 1; i <= n; i++) {
numbers += i + ' ';
}
numbers += '\n'; // <-- add a newline character
for (var i = 0; i < n; i++) {
numbers = numbers.replace(i, '*');
output1 += numbers;
output2 = numbers + output2; // <-- add reversed
}
console.log(output1 + output2); // <-- output both
.as-console-wrapper { max-height: 100% !important; top: 0; }
Sticking with something similar to your approach:
var n = 5;
var numbers = '';
for (var i = 1; i <= n; i++) {
numbers += i + ' ';
}
for (var i = 0; i < n; i++) {
numbers = numbers.substr (0, i * 2) + '*' + numbers.substr (i * 2 + 1);
console.log(numbers);
};
for (var i = n - 1; i >= 0; i--) {
console.log(numbers);
numbers = numbers.substr (0, i * 2) + (i + 1) + numbers.substr (i * 2 + 1);
};
The disadvantage of this approach is that it only works for 0-9 because the string positions break when the numbers aren't single digits.
The way I might approach the problem is by having a variable that keeps track of up to which number needs to be an asterisk, doing the first half, then using a whole new for loop to do the second half.
For instance,
String result = '';
String line = '';
int counter = 1;
for (int line = 1; line =< 5; line++) {
for (int i = 1; i =< 5; i++) { // note that we start at 1, since the numbers do
if (i <= counter) {
line += '*'; // use asterisk for positions less than or equal to counter
else {
line += i; // otherwise use the number itself
}
line += ' '; // a space always needs to be added
}
result += line + '\n'; // add the newline character after each line
counter++; // move the counter over after each line
}
Then you can do the same loop, but make the counter go backwards. To do that, set counter to 5 before you begin the loop (since Strings are zero-indexed) and do counter-- after each line.
Alternatively if you don't want to write two loops, you can increase the outer for loop's limit to 10 and have an if statement check if you should be subtracting from counter instead of adding, based on the value of line
Decided to use this as an excuse to get more practice with immutable mapping and reducing. I used an array to hold all the rows, and reduce them at the end to a string. Each row starts as an array holding 1 to n, and each column number is then mapped to an asterisk based on the case:
if rowIndex <= number:
rowIndex.
else:
rowIndex - (2 * (rowIndex - number) - 1)
Essentially, [n + 1, n * 2] maps to (1, 3, 5, ..., n - 3, n - 1), which subtracted from the original range becomes [n, 1]. For the row, check if the currently selected column is less than or equal to its row's translated index, and return an asterisk or the number.
// expansion number (n by 2n)
const maxNum = 5;
// make an array to size to hold all the rows
const result = Array(maxNum * 2)
// Fill each row with an array of maxNum elements
.fill(Array(maxNum).fill())
// iterate over each row
.map((row, rowIndex) =>
// iterate over each column
row.map((v, column) => (
// check if the column is less than the translated rowIndex number (as mentioned above)
column < ((rowIndex <= maxNum) ?
rowIndex + 1 :
2 * maxNum - rowIndex
// if it is, replace it with an asterisk
)) ? "*" : column + 1)
// combine the row into a string with each column separated by a space
.reduce((rowAsString, col) => rowAsString + " " + col)
// combine all rows so they're on new lines
).reduce((rowAccum, row) => rowAccum + "\n" + row);
console.log(result);
Related
Hi i am trying to create an array that always has a total of 100 based on random numbers. I get it to work when there is 2 or 3 rows but i can't get it to work if there are more as 4. Meaning i need to change the middle section. Here is simple code i made: (the length is the number of rows in the array)
var array = []
var length = 3; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i == length-1){
if(length > 2){
calculate = 100 - number;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
How should i change the middle section to be able to capture the numbers?
There are two errors in this code:
First:
You should change the == to < in order to be able to loop more then 3 times:
if(i > 0 && i == length-1)
Second:
I think your error occurs on the following line. You subtract number from 100 which is the previous generated number. You should instead generate a random number from everything that is left:
calculate = 100 - number;
So I think you should subtract the totalProcessed value instead.
calculate = 100 - totalProcessed;
Full working snippet:
var array = []
var length = 5; //4 , 5 , 6 ...
var number;
var calculate;
var totalProcessed;
for (i = 0; i < length; i++) {
// FIRST ONE
if(i == 0){
number = Math.floor(Math.random() * 100) + 1;
console.log(number);
totalProcessed = number;
array.push(number)
}
// MIDDLE SECTION
if(i > 0 && i < length-1){
if(length > 2){
calculate = 100 - totalProcessed;
number = Math.floor(Math.random() * calculate) + 1
totalProcessed = totalProcessed + number;
console.log(number);
array.push(number)
}
}
// LAST ONE
if(i == length -1){
var lastOne = 100-totalProcessed;
console.log(lastOne);
array.push(lastOne)
}
}
console.log(array);
let total = 0;
array.forEach(el => total += el)
console.log(total)
You should replace the "==" in the if statement of the middle section by "<".
I found your approach a bit hard to comprehend. Is the question setup same as what code is trying to do? Therefore I wrote an alternate example that solves the question (as currently explained):
let limit = 100;
const numbers = [...Array(limit)].map(() => {
const random = Math.floor(Math.random() * 100) + 1;
if (limit - random > 0) {
limit -= random;
return random;
}
return null;
}).concat(limit).filter((num) => num)
console.log(numbers);
It goes through 100 iterations (in case there would come only 1's :D) and then decreases the limit. And if next random number fits into limit, it's added to the result, otherwise it's a null.
And if it happens that after 100 iterations there are still limit left, it's concatenated to an existing array. Finally we filter out all the "nulls" (numbers that didn't fit in to limit) and voila.
I need some function to return pattern like this :
= * = * =
* = * = *
= * = * =
* = * = *
= * = * =
i try this but i cant get it:
function cetakGambar(angka){
let result = ''
for(let i=0; i<=angka; i++){
for(let j=0; j<=i; j++){
result += '= '
}
for(let k=0; k == i; k++){
result += ' *'
}
result += '\n'
}
return result
}
console.log(cetakGambar(5))
what looping i need to get that pattern
You were on the right track with the two nested loops. Here's an example small modification to solve the problem:
function cetakGambar(angka){
let result = ''
for(let i = 0; i < angka; i++){
for(let j = 0; j < angka; ++j) {
result += ((i + j) % 2 == 0) ? '= ' : '* ';
}
result += '\n';
}
return result
}
For each i a row is generated by looping over j. For each j we append either an = or * , depending on if after adding i and j the result is divisible by two (to create the alternating pattern). After each line a \n (newline) is appended.
Here's an ES6 solution w/o explicit iteration. It is not particularly concise and probably not too useful in this case but fun (IMHO), so I wanted to share it.
It uses Array.from to apply a generator function yielding the next symbol (* or =) for each cell and concats cells with spaces and rows with newlines.
// Utility to apply function <fn> <n> times.
function times(n, fn) {
return Array.from({ length: n }, fn);
}
// Generator function yielding the next symbol to be drawn.
//
function cetakGambar(angka) {
let generator = (function*() {
let [i, s1, s2] = [0, "*", "="];
while (true) {
// Make sure to start a new line with a different symbol for
// even rows in case <angka> is even
if (i++ % angka === 0 && angka % 2 === 0) {
[s1, s2] = [s2, s1];
}
// limit the generator to the number of values we actually need
if (i === angka * angka + 1) return;
yield i % 2 === 0 ? s1 : s2;
}
})();
return times(
angka,
() => times(angka, () => generator.next().value).join(" ") // join symbols w/ spaces ...
).join("\n"); // ... and lines w/ newline
}
console.log(cetakGambar(5));
Codesandbox here: https://codesandbox.io/s/wispy-http-mfxgo?file=/src/index.js
Different approach using one loop
function gen(row,col){
var i = 0;
var out="";
do {
if(i%col==0) out+="\n"
out += (i % 2) == 0 ? ' = ' : ' * ';
i++;
}
while (i < row*col);
return out;
}
console.log(gen(5,5));
I have been struggling with this challenge and can't seem to find where I'm failing at:
Some numbers have funny properties. For example:
89 --> 8¹ + 9² = 89 * 1
695 --> 6² + 9³ + 5⁴= 1390 = 695 * 2
46288 --> 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
Given a positive integer n written as abcd... (a, b, c, d... being digits) and a positive integer p we want to find a positive integer k, if it exists, such as the sum of the digits of n taken to the successive powers of p is equal to k * n. In other words:
Is there an integer k such as : (a ^ p + b ^ (p+1) + c ^(p+2) + d ^ (p+3) + ...) = n * k
If it is the case we will return k, if not return -1.
Note: n, p will always be given as strictly positive integers.
digPow(89, 1) should return 1 since 8¹ + 9² = 89 = 89 * 1
digPow(92, 1) should return -1 since there is no k such as 9¹ + 2² equals 92 * k
digPow(695, 2) should return 2 since 6² + 9³ + 5⁴= 1390 = 695 * 2
digPow(46288, 3) should return 51 since 4³ + 6⁴+ 2⁵ + 8⁶ + 8⁷ = 2360688 = 46288 * 51
I'm new with javascript so there may be something off with my code but I can't find it. My whole purpose with this was learning javascript properly but now I want to find out what I'm doing wrong.I tried to convert given integer into digits by getting its modulo with 10, and dividing it with 10 using trunc to get rid of decimal parts. I tried to fill the array with these digits with their respective powers. But the test result just says I'm returning only 0.The only thing returning 0 in my code is the first part, but when I tried commenting it out, I was still returning 0.
function digPow(n, p){
// ...
var i;
var sum;
var myArray= new Array();
if(n<0)
{
return 0;
}
var holder;
holder=n;
for(i=n.length-1;i>=0;i--)
{
if(holder<10)
{
myArray[i]=holder;
break;
}
myArray[i]=holder%10;
holder=math.trunc(holder/10);
myArray[i]=math.pow(myArray[i],p+i);
sum=myArray[i]+sum;
}
if(sum%n==0)
{
return sum/n;
}
else
{
return -1;
}}
Here is the another simple solution
function digPow(n, p){
// convert the number into string
let str = String(n);
let add = 0;
// convert string into array using split()
str.split('').forEach(num=>{
add += Math.pow(Number(num) , p);
p++;
});
return (add % n) ? -1 : add/n;
}
let result = digPow(46288, 3);
console.log(result);
Mistakes
There are a few problems with your code. Here are some mistakes you've made.
number.length is invalid. The easiest way to get the length of numbers in JS is by converting it to a string, like this: n.toString().length.
Check this too: Length of Number in JavaScript
the math object should be referenced as Math, not math. (Note the capital M) So math.pow and math.trunc should be Math.pow and Math.trunc.
sum is undefined when the for loop is iterated the first time in sum=myArray[i]+sum;. Using var sum = 0; instead of var sum;.
Fixed Code
I fixed those mistakes and updated your code. Some parts have been removed--such as validating n, (the question states its strictly positive)--and other parts have been rewritten. I did some stylistic changes to make the code more readable as well.
function digPow(n, p){
var sum = 0;
var myArray = [];
var holder = n;
for (var i = n.toString().length-1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder/10);
myArray[i] = Math.pow(myArray[i],p+i);
sum += myArray[i];
}
if(sum % n == 0) {
return sum/n;
} else {
return -1;
}
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
My Code
This is what I did back when I answered this question. Hope this helps.
function digPow(n, p){
var digPowSum = 0;
var temp = n;
while (temp > 0) {
digPowSum += Math.pow(temp % 10, temp.toString().length + p - 1);
temp = Math.floor(temp / 10);
}
return (digPowSum % n === 0) ? digPowSum / n : -1;
}
console.log(digPow(89, 1));
console.log(digPow(92, 1));
console.log(digPow(46288, 3));
You have multiple problems:
If n is a number it is not going to have a length property. So i is going to be undefined and your loop never runs since undefined is not greater or equal to zero
for(i=n.length-1;i>=0;i--) //could be
for(i=(""+n).length;i>=0;i--) //""+n quick way of converting to string
You never initialize sum to 0 so it is undefined and when you add the result of the power calculation to sum you will continually get NaN
var sum; //should be
var sum=0;
You have if(holder<10)...break you do not need this as the loop will end after the iteration where holder is a less than 10. Also you never do a power for it or add it to the sum. Simply remove that if all together.
Your end code would look something like:
function digPow(n, p) {
var i;
var sum=0;
var myArray = new Array();
if (n < 0) {
return 0;
}
var holder;
holder = n;
for (i = (""+n).length - 1; i >= 0; i--) {
myArray[i] = holder % 10;
holder = Math.trunc(holder / 10);
myArray[i] = Math.pow(myArray[i], p + i);
sum = myArray[i] + sum;
}
if (sum % n == 0) {
return sum / n;
} else {
return -1;
}
}
Note you could slim it down to something like
function digPow(n,p){
if( isNaN(n) || (+n)<0 || n%1!=0) return -1;
var sum = (""+n).split("").reduce( (s,num,index)=>Math.pow(num,p+index)+s,0);
return sum%n ? -1 : sum/n;
}
(""+n) simply converts to string
.split("") splits the string into an array (no need to do %10 math to get each number
.reduce( function,0) call's the array's reduce function, which calls a function for each item in the array. The function is expected to return a value each time, second argument is the starting value
(s,num,index)=>Math.pow(num,p+index+1)+s Fat Arrow function for just calling Math.pow with the right arguments and then adding it to the sum s and returning it
I have created a code that does exactly what you are looking for.The problem in your code was explained in the comment so I will not focus on that.
FIDDLE
Here is the code.
function digPow(n, p) {
var m = n;
var i, sum = 0;
var j = 0;
var l = n.toString().length;
var digits = [];
while (n >= 10) {
digits.unshift(n % 10);
n = Math.floor(n / 10);
}
digits.unshift(n);
for (i = p; i < l + p; i++) {
sum += Math.pow(digits[j], i);
j++;
}
if (sum % m == 0) {
return sum / m;
} else
return -1;
}
alert(digPow(89, 1))
Just for a variety you may do the same job functionally as follows without using any string operations.
function digPow(n,p){
var d = ~~Math.log10(n)+1; // number of digits
r = Array(d).fill()
.map(function(_,i){
var t = Math.pow(10,d-i);
return Math.pow(~~((n%t)*10/t),p+i);
})
.reduce((p,c) => p+c);
return r%n ? -1 : r/n;
}
var res = digPow(46288,3);
console.log(res);
Yet Another (Project Euler) Fibonacci Question: Using (vanilla) javascript, I'm trying to sum the even numbers <= a given limit:
First, something is wrong with my 'if' statement, as some of the results (below) are wrong:
function fibonacciSum(limit) {
var limit = limit;
var series = [1,2];
var sum = 0;
var counter = 0;
for (var i=1; i<=33; i++) { // 33 is arbitrary, because I know this is more than enough
var prev1 = series[series.length-1];
var prev2 = series[series.length-2];
var newVal = prev1+prev2;
series.push(newVal);
counter ++;
console.log("series "+ counter + " is: " + series);
if (series[i] % 2 === 0 && series[i] <= limit) { // intending to sum only even values less than/equal to arbitrary limit
// sum = sum + series[i];
sum += series[i];
}
/*
var sum = series.reduce(function(a,b) {
/*
possible to filter here for even numbers? something like:
if (a %2 === 0)
*/
return a+b;
});
*/
console.log("SUM " + counter + ": " + sum);
} // for loop
} // fibonacci
fibonacciSum(4000000);
Results:
series 1 is: 1,2,3
SUM 1: 2
series 2 is: 1,2,3,5
SUM 2: 2
series 3 is: 1,2,3,5,8
SUM 3: 2 // looking for a '10' here
series 4 is: 1,2,3,5,8,13
SUM 4: 10
series 5 is: 1,2,3,5,8,13,21
SUM 5: 10
series 6 is: 1,2,3,5,8,13,21,34
SUM 6: 10 // looking for '44' here
Can someone please explain why neither of these working as intended?
if (series[i] % 2 === 0) { ...
... or
if (series[i] % 2 === 0 && series[i] <= limit) { ...
And secondly, as you can see I had also tried to use series.reduce(... but I can't figure how to sum only the even values; is that doable/cleaner?
Thank you,
Whiskey T.
No need for arrays. Use three variables for let's say previous, current and next numbers in fibonacci sequence.
We can also begin the sequence with 2 an 3 because there are no other even numbers that will affect the result.
We initialize the sum of even numbers with 2 because it's the current number and it's even. In a do...while we advance with the numbers in sequence and if the new numbers are even we add them to the sum. Stop when limit is reached.
function fibEvenSum(limit) {
var prev = 1,
current = 2,
next;
var sum = 2;
do {
next = prev + current;
prev = current;
current = next;
if (current >= limit)
break;
if (current % 2 == 0)
sum += current;
} while (true)
return sum;
}
This algorithm can be improved using properties of odd and even numbers:
odd + odd = even
even + even = even
even + odd = odd
This should work for you...
var fibonacciSum = function(limit) {
var nMinus2 = 1, nMinus1 = 2, evensFound = [2], sum = nMinus1;
while (sum <= limit){
var n = nMinus1 + nMinus2;
if (n % 2 == 0){
sum += n;
if (sum > limit){
break;
}
evensFound.push(n);
}
nMinus2 = nMinus1;
nMinus1 = n;
}
console.log("Evens found - " + evensFound);
return evensFound;
};
var evensFound1 = fibonacciSum(4),
evensFound2 = fibonacciSum(10),
evensFound3 = fibonacciSum(60),
evensFound4 = fibonacciSum(1000);
$(evenResults).append(evensFound1
+ "<br/>" + evensFound2
+ "<br/>" + evensFound3
+ "<br/>" + evensFound4);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="evenResults"></div>
A solution in the spirit of the one your attempted — with arrays — though as pointed out, they are not necessary.
var i = 0, sequence = [1, 2], total = 0;
while (sequence.slice(-1)[0] < 4000000) {
sequence.push(sequence.slice(-1)[0] + sequence.slice(-2)[0]);
}
for ( i; i <= sequence.length; i++ ) {
if ( sequence[i] % 2 === 0 ) {
total += sequence[i];
}
}
I am trying to write a single javascript function that will take in a list of numbers as arguments and will output the number of odd number, number of negative numbers, will average the numbers, and will output the median. I believe I basically have completed all of the code, but am either confusing my syntax or am incorrectly returning.
Code:
var arrayAnalyze = function(numbers){
var oddNum = []; //Array of odd numbers
var negNum = []; //Array of negative numbers
var numSum = 0; // Sum of all numbers
var avgNum = 0; //Average of all numbers
var midNum = []; //Median number
//Return odd numbers to oddNum array
for (i = 0; i < numbers.length; i++){
if (numbers[i] % 2 !== 0){
oddNum.push(numbers[i]);
}
}
//Return negative numbers to negNum array
for (i = 0; i < numbers.length; i++){
if (Math.abs(numbers[i]) + numbers[i] === 0){
negNum.push(numbers[i]);
}
}
//Return sum of all numbers to numSum variable
for (i = 0; i < numbers.length; i++){
numSum += i;
}
//Return average of numbers to avgNum variable
avgNum = numSum / numbers.length;
//Return median of numbers to midNum array
numbers.sort(function(a,b){return a - b;});
var evenSplit = Math.floor(numbers.length / 2);
if(numbers.length % 2){
midNum = numbers[evenSplit];
}else{
midNum = (numbers[evenSplit - 1] + numbers[evenSplit]) / 2.0; }
midNum.push();
return "Odds: " + oddNum.length, "Negatives: " + negNum.length, "Average: " + avgNum.toFixed(2), "Median: " + midNum[0];
};
console.log(arrayAnalyze(7, -3, 0, 12, 44, -5, 3));
Output:
TypeError: numbers.sort is not a function
There's a number of errors that you'd want to correct - comments inline
var arrayAnalyze = function (numbers) {
var oddNum = []; //Array of odd numbers
var negNum = []; //Array of negative numbers
var numSum = 0; // Sum of all numbers
var avgNum = 0; //Average of all numbers
var midNum = []; //Median number
//Return odd numbers to oddNum array
for (i = 0; i < numbers.length; i++) {
// always check the element at index, i is just the index
if (numbers[i] % 2 !== 0) {
// return exits the currently running function! (not the block)
oddNum.push(numbers[i]);
}
}
//Return negative numbers to negNum array
for (i = 0; i < numbers.length; i++) {
// exclude 0 here
if (Math.abs(numbers[i]) + numbers[i] === 0 && numbers[i]) {
negNum.push(numbers[i]);
}
}
//Return sum of all numbers to numSum variable
for (i = 0; i < numbers.length; i++) {
numSum += numbers[i];
}
//Return average of numbers to avgNum variable
avgNum = numSum / numbers.length;
//Return median of numbers to midNum array
// if you are using a function you need to invoke it to get it's value
midNum.push((function median(numbers) {
// note that this will actually sort the elements of the array you pass in in-place
numbers.sort(function (a, b) { return a - b; });
var evenSplit = Math.floor(numbers.length / 2);
if (numbers.length % 2) {
return numbers[evenSplit];
} else {
return (numbers[evenSplit - 1] + numbers[evenSplit]) / 2.0;
}
})(numbers));
// use + to concatenate the strings, otherwise it just becomes a bunch of comma separated expressions
return "Odds: " + oddNum.length + ",Negatives: " + negNum.length + ",Average: " + avgNum.toFixed(2) + ",Median: " + midNum[0];
};
// an array is passed in using square brackets
console.log(arrayAnalyze([7, -3, 0, 12, 44, -5, 3]));
when a function hits a return statement it will exit out meaning the any code beneath the return will not get executed.
In your odd number sorter you use the %/Modulus on the counter/index rather than numbers[i] to use it on each element of the numbers array parameter. This also needs fixed when you push to the appropriate results array. I have spotted this same concept being done multiple times throughout the function so I would go back and correct that as it would break a couple things.
Also to give you a tip in the right direction in terms of learning return like other users are saying, let's take a look at this part of your code:
for (i = 0; i < numbers.length; i++){
return numSum += i;
}
You do not need to return numSum as your are returning its value later at the end. Just updated the variable you initialized at the beginning by doing the following (also updated in regards to my suggestion above):
for (i = 0; i < numbers.length; i++){
numSum += numbers[i];
}
You cleary are pretty confused about how the return keyword works; I suggest you to check out some documentation here and here.
As an example, you need to change that piece of code
if (numbers % 2 !== 0){
return oddNum.push(numbers);
}else{
return false;
}
into
if (numbers % 2 !== 0){
oddNum.push(numbers);
}
All the others if structures have the same error.
I believe you have a fundamental misunderstand of what return does. MDN has a page on it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return#Examples
return interrupts code execution, exits the innermost function and returns a value to the caller.
function myFunction() {
return "foo";
alert("This will never be reached!");
}
alert(myFunction()) // Equivalent to alert("foo").
For example, in your code:
//Return odd numbers to oddNum array
for (i = 0; i < numbers.length; i++){
if (i % 2 !== 0){
return oddNum.push(i); // <- code execution will stop here
}else{
return false; // <- or here, whichever is reached first.
}
}
Which means your loop will never execute for more than one iteration. So when you call
console.log(arrayAnalyze(7, -3, 0, 12, 44, -5, 3));
The first value is odd, so the function will stop at return oddNum.push(i);. And since oddNum.push(i) itself returns nothing (undefined), arrayAnalyze will return undefined too, and the log will be equivalent to
console.log(undefined);
Which is what you are seeing.
In this case the returns are completely unnecessary and the loop should read:
//Return odd numbers to oddNum array
for (i = 0; i < numbers.length; i++){
if (i % 2 !== 0){
oddNum.push(i); // <- now code execution is not interrupted!
}
}
And so on, through the rest of the code.
Also, at the end you declare a function called median:
//Return median of numbers to midNum array
function median(numbers) {
[...]
}
But you never invoke it (calling median(someValue)), which means the code inside it will never be executed either. I haven't checked the code for mathematical correctness, but I believe you should just remove the median declaration and leave its body inside the main arrayAnalyze function.
Your code should look like this :
var arrayAnalyze = function (numbers) {
var oddNum = []; //Array of odd numbers
var negNum = []; //Array of negative numbers
var numSum = 0; // Sum of all numbers
var avgNum = 0; //Average of all numbers
var midNum = []; //Median number
//Return odd numbers to oddNum array
for (i = 0; i < numbers.length; i++) {
if (i % 2 !== 0) {
oddNum.push(numbers[i]);
}
}
//Return negative numbers to negNum array
for (i = 0; i < numbers.length; i++) {
if (Math.abs(numbers[i]) + numbers[i] === 0) {
negNum.push(numbers[i]);
}
}
//Return sum of all numbers to numSum variable
for (numbers[i] = 0; numbers[i] < numbers.length; numbers[i]++) {
numSum += numbers[i];
}
//Return average of numbers to avgNum variable
avgNum = numSum / numbers.length;
//Return median of numbers to midNum array
var newArrayOfNumber = numbers;
newArrayOfNumber.sort();
var evenSplit = Math.floor(newArrayOfNumber.length / 2);
if (newArrayOfNumber.length % 2) {
midNum = newArrayOfNumber[evenSplit];
} else {
midNum = (newArrayOfNumber[evenSplit - 1] + newArrayOfNumber[evenSplit]) / 2.0;
}
return "Odds: " + oddNum.length + ", Negatives: " + negNum.length +", Average: " + avgNum.toFixed(2) +", Median: " + midNum;
};
When you call the function you should pass a array to it, so just add [] to your numbers like this : arrayAnalyze([7, -3, 0, 12, 44, -5, 3])
it should return :"Odds: 3, Negatives: 3, Average: 3.50, Median: 7.5"
When you want to add some number to a array in a for block or a if block, dont use return, just do the operation and if you want to break the for loop, use the line :
Break;
and when you want to access the number in your for loop, you should call the array and not only the i, like this : number[i]
espering that it help you
sorry for my mistakes in writting in english