Getting sum using += doesn't work in here. Why? - javascript

I'm trying to return true or false if given value is narcissistic number.
After assigned empty variable sum, then try to getting sum using +=
But, I don't know It doesn't work in here.
function narcissistic(n) {
let arr = Array.from(String(n), Number);
// ex) 999 => [9,9,9]
let sum;
arr.forEach((e) => {
sum += Math.pow(e,arr.length) ;
})
return sum === n ? true: false
}
It results in NaN. Have no idea why?
So I had to use this one and It works.
function narcissistic(n) {
let arr = Array.from(String(n), Number);
// ex) 999 => [9,9,9]
let newArr = [];
arr.forEach((e) => {
newArr.push(Math.pow(e,arr.length)) ;
})
let sum = newArr.reduce((a,b) => a+b);
return sum === n ? true: false
}
So my question is why the first one doesn't work when it comes to sum += ??

You need to make sum equal to 0 - it starts out life as undefined, and any mathematics with undefined leads to NaN.
let sum = 0;
This should fix your problem.
A more concise way to do this is with reduce:
let sum = arr.reduce((a, c) => a + Math.pow(c, arr.length));

We should initialize your variable before referencing.
let sum = 0;
It could solve your issue.

Related

reduce method in javascript gets undefined

How do I use the reduce method in solving this problem? I keep getting undefined. I am trying to only print out the numbers that are bigger while going through the loop. so for example [ 1,4,2,9,1,12] will give me the printout of 1,4,9,12- here is what I got... and I keep getting undefined for the accumulator????
**
function main(array){
let myNum;
let answer=[];
outPut = array.reduce((accumulator, element) => {
const num = accumulator;
myNum= num > element? answer.push(num):
answer.push(element);
}, 0);
console.log(outPut);
}**
main([20, 3, 22, 15, 6, 1]);
You need to return the accumulator in reduce().
A simpler version is to check the index is zero or value is greater than previous in the accumulator to determine whether to add current value or not
const data = [ 1,4,2,9,1,2,12];
const res = data.reduce((a, c, i) => {
return (!i || c > a[a.length-1]) ? a.concat(c) : a;
},[])
console.log(res)
If you want [1,4,2,9,1,12] to return [1,4,9,12], array.reduce isn't the way to go.
Try
function sortArray(array) {
const sortedArray = array
.sort((a, b) => a - b) //sort by ascending
.filter((e, index) => array.indexOf(e) == index) //remove duplicates
console.log(sortedArray);
}
That's because the reduce() works with callback which return nunber. You are not returning anything.
But the main issue is the fact you are pushing items into answer. But then you are trying to log outPut, which is not initialized and the only value it could have is from wrongly used reduce().
Try this:
function main(array){
let myNum;
let answer=[];
array.reduce((accumulator, element) => {
const num = accumulator;
let biggerOne;
if(num > element) {
biggerOne = num;
} else {
biggerOne = element;
}
answer.push(biggerOne);
return biggerOne;
}, 0);
console.log(answer);
}**
main([20, 3, 22, 15, 6, 1]);

Why i cant use for this way?

The plan is:
sort 'arr' from less to greater.
push values in range of both number from arr, inclusively.
find smallest common number which dividible on each value from 'arrForAll' without reminder.
Assign to 'i' first value from 'arrForAll'.
Output 'while' condition isn't false. Condition is: 'i' don't divide on each value from 'arrForAll' without reminder.
I tried this:
function smallestCommons(arr) {
let sortedArray = arr.sort();
let arrForAll = []
for (let i = sortedArray[0]; i < sortedArray[1] + 1; i++) {
arrForAll.push(i)
}
for (let i = sortedArray[1]; arrForAll.every(x => i % x !== 0); i += i) {
console.log(i)
}
return arr;
}
console.log(smallestCommons([1, 5]));
But console output nothing.
What's wrong in code?
In conditioin of for loop it must use logic operators '<','>', etc.
So this situation while loop is more suitable solution
function smallestCommons(arr) {
var i=0;
let sortedArray = arr.sort();//here store sorted value
let arrForAll=[]
for(let i=sortedArray[0];i<sortedArray[1]+1;i++){
arrForAll.push(i)
}//store [x to y]
while(true){
i+=sortedArray[1];
if(arrForAll.every(x => i % x == 0)){
break;
}
}
return i;}
console.log(smallestCommons([23, 18]));//returns 6056820, [1,5] will return 60

Arrow Function of JavaScript question - Multiple Arrow Function nesting

I saw a answer when I am practicing JS on leetcode, but I can't understand what this mean. can anyone expand the code? or tell me how to read this.
https://leetcode.com/problems/running-sum-of-1d-array/discuss/702025/one-liner
let runningSum = nums => nums.map((sum => el => sum += el)(0));
console.log(runningSum([1,2,3,4]))
Original function
let runningSum = nums => nums.map((sum => el => sum += el)(0));
(sum => el => sum += el) is
function f1(sum) {
return function f2(el) {
return sum += el;
}
}
(or in arrow format as shown by #Alterlife)
The original function then transforms into
let runningSum = nums => nums.map(f1(0));
then nums.map(f1(0));
becomes
const result = [];
const f2 = f1(0);
for(let i = 0; i < nums.length; ++i) {
const num = nums[i];
result.push(f2(num));
}
So all together, the original function transforms into
const nums = [1,2,3,4];
function f1(sum) {
return function f2(el) {
return sum += el;
}
}
const result = [];
const f2 = f1(0);
for(let i = 0; i < nums.length; ++i) {
const num = nums[i];
result.push(f2(num));
}
console.log(result);
Let's try and break it down.
(sum => el => sum += el) , is equivalent to:
const mySumFunction = (sum) => {
const addToSum = (el) => {
sum += el;
return sum;
}
return addToSum;
}
This is a function that takes in a parameter - a starting sum. The sum parameter is also local variable within the function's scope.
When you call mySumFunction, it returns another function that adds to the local scoped variable sum and returns the total sum so far.
In effect, it creates a "function with memory" that returns the sum of everything that has been passed into it so far.
You can test this out as follows:
cumilativeSum = mySumFunction(0)
console.log(v(1)) // returns 1
console.log(v(1)) // returns 2
console.log(v(4)) // returns 6
Now let's look at the code as a whole.
let runningSum = nums => nums.map((sum => el => sum += el)(0));
The entire snippet passed into the map function: (sum => el => sum += el)(0) creates a "sum function with memory" that starts at 0, as we figured out above.
We're passing each of the numbers in an array to it and creating an array with the cumulative sum.
Let's take (sum => el => sum += el)(0) this self invocation arrow function for 1st iteration of map. Up on execution it return another arrow function el => sum += el. The value of sum is 0 which is passed as argument. Now keep come to our map 1st iteration
let runningSum = nums => nums.map(el => sum = 0 + el);
It returns 1. So, for the 2nd iteration, the value of the sum is 1 and el is 2.
so it returns 3, then 6 and then 10.
let runningSum = (nums) =>
nums.map(
(function (sum) {
return (el) => (sum += el);
})(0)
);
console.log(runningSum([1, 2, 3, 4]));

how to sum an array of arrays in javascript

I currently have this function
function radius(d) {
return d.values[0].environment["4*"];
console.log(d);
}
However id liked to be able to average all of the 4* environment values for each document(there are 6 in the example below) and return this as the radius. Im new to JS so no idea how to do this. can you help. here is the structure of the data
You can use reduce function:
function radius(d) {
return d.values.reduce(function(avg, item, index, array) {
return avg + item.environtment['4*'] /array.length
},0)
}
It's tough to answer the question accurately without testing the whole data structure. Based on what you've provided this should work:
function radius(d) {
let sum = 0;
for (let i=0; i<d.length; i++) {
let num = parseInt(d[i].environment['4*']);
if (!isNaN(num)) sum += num;
}
return sum;
}
We loop through the array, and if environment['4*'] is a valid number we sum it up. Functionally it would be:
function radius(d) {
const filtered = d.values.filter((x) => {
let num = parseInt(x.environment['4*']);
return !isNaN(num);
});
const sum = filtered.reduce((acc, val) => {
return acc+val;
},0)
return sum/filtered.length;
}

How to adjust return values of map() function?

I have been trying to make a excercise in the course I am taking. At the end, I did what was asked, but I personally think I overdid too much and the output is not convenient -- it's a nested array with some blank arrays inside...
I tried to play with return, but then figured out the problem was in the function I used: map always returns an array. But all other functions, which are acceptable for arrays (in paticular forEach and I even tried filter) are not giving the output at all, only undefined. So, in the end, I have to ask you how to make code more clean with normal output like array with just 2 needed numbers in it (I can only think of complex way to fix this and it'll add unneeded junk to the code).
Information
Task:
Write a javascript function that takes an array of numbers and a target number. The function should find two different numbers in the array that, when added together, give the target number. For example: answer([1,2,3], 4) should return [1,3]
Code
const array1 = [1, 2, 3];
const easierArray = [1, 3, 5] //Let's assume number we search what is the sum of 8
const findTwoPartsOfTheNumber = ((arr, targetNum) => {
const correctNumbers = arr.map((num, index) => {
let firstNumber = num;
// console.log('num',num,'index',index);
const arrayWeNeed = arr.filter((sub_num, sub_index) => {
// console.log('sub_num',sub_num,'sub_index',sub_index);
if (index != sub_index && (firstNumber + sub_num) === targetNum) {
const passableArray = [firstNumber, sub_num] //aka first and second numbers that give the targetNum
return sub_num; //passableArray gives the same output for some reason,it doesn't really matter.
}
})
return arrayWeNeed
})
return correctNumbers;
// return `there is no such numbers,that give ${targetNum}`;
})
console.log(findTwoPartsOfTheNumber(easierArray, 8));
console.log(findTwoPartsOfTheNumber(array1, 4));
Output
[[],[5],[3]]
for the first one
You can clean up the outpu by flatting the returned arrays :
return arrayWeNeed.flat();
and
return correctNumbers.flat();
const array1 = [1, 2, 3];
const easierArray = [1, 3, 5] //Let's assume number we search what is the sum of 8
const findTwoPartsOfTheNumber = ((arr, targetNum) => {
const correctNumbers = arr.map((num, index) => {
let firstNumber = num;
// console.log('num',num,'index',index);
const arrayWeNeed = arr.filter((sub_num, sub_index) => {
// console.log('sub_num',sub_num,'sub_index',sub_index);
if (index != sub_index && (firstNumber + sub_num) === targetNum) {
const passableArray = [firstNumber, sub_num] //aka first and second numbers that give the targetNum
return sub_num; //passableArray gives the same output for some reason,it doesn't really matter.
}
})
return arrayWeNeed.flat();
})
return correctNumbers.flat();
// return `there is no such numbers,that give ${targetNum}`;
})
console.log(findTwoPartsOfTheNumber(easierArray, 8));
console.log(findTwoPartsOfTheNumber(array1, 4));
However, using a recursive function could be simpler :
const answer = (arr, num) => {
if (arr.length < 1) return;
const [first, ...rest] = arr.sort();
for (let i = 0; i < rest.length; i++) {
if (first + rest[i] === num) return [first, rest[i]];
}
return answer(rest, num);
};
console.log(answer([1, 2, 3], 4));
console.log(answer([1, 3, 5], 8));
It looks like you are trying to leave .map() and .filter() beforehand, which you can't (without throwing an error). So I suggest a normal for approach for this kind of implementation:
const array1 = [1,2,3];
const easierArray = [1,3,5] //Let's assume number we search what is the sum of 8
const findTwoPartsOfTheNumber = (arr,targetNum) =>{
for(let index = 0; index < arr.length; index++) {
let firstNumber = arr[index];
// console.log('num',num,'index',index);
for(let sub_index = 0; sub_index < arr.length; sub_index++){
const sub_num = arr[sub_index];
// console.log('sub_num',sub_num,'sub_index',sub_index);
if (index != sub_index && (firstNumber + sub_num) === targetNum){
const passableArray = [firstNumber,sub_num]//aka first and second numbers that give the targetNum
return passableArray; //passableArray gives the same output for some reason,it doesn't really matter.
}
}
}
return `there is no such numbers,that give ${targetNum}`;
}
console.log(findTwoPartsOfTheNumber(easierArray,8));
console.log(findTwoPartsOfTheNumber(array1,4));
console.log(findTwoPartsOfTheNumber(array1,10));
I've just grab your code and changed map and filter to for implementation.
There doesn't appear to be any requirement for using specific array functions (map, forEach, filter, etc) in the problem statement you listed, so the code can be greatly simplified by using a while loop and the fact that you know that the second number has to be equal to target - first (since the requirement is first + second == target that means second == target - first). The problem statement also doesn't say what to do if no numbers are found, so you could either return an empty array or some other value, or even throw an error.
const answer = (list, target) => {
while (list.length > 0) { // Loop until the list no longer has any items
let first = list.shift() // Take the first number from the list
let second = target - first // Calculate what the second number should be
if (list.includes(second)) { // Check to see if the second number is in the remaining list
return [first, second] // If it is, we're done -- return them
}
}
return "No valid numbers found" // We made it through the entire list without finding a match
}
console.log(answer([1,2,3], 3))
console.log(answer([1,2,3], 4))
console.log(answer([1,2,3], 7))
You can also add all the values in the array to find the total, and subtract the total by the target to find the value you need to remove from the array. That will then give you an array with values that add up to the total.
let arr1 = [1, 3, 5]
const target = 6
const example = (arr, target) => {
let total = arr.reduce((num1, num2) => {
return num1 + num2
})
total = total - target
const index = arr.indexOf(total)
if (index > -1) {
return arr.filter(item => item !== total)
}
}
console.log(example(arr1, target))
Map and filter are nice functions to have if you know that you need to loop into the whole array. In your case this is not necessary.
So you know you need to find two numbers, let's say X,Y, which belong to an array A and once added will give you the target number T.
Since it's an exercise, I don't want to give you the working code, but here is a few hints:
If you know X, Y must be T - X. So you need to verify that T - X exists in your array.
array.indexOf() give you the position of an element in an array, otherwise -1
If X and Y are the same number, you need to ensure that their index are not the same, otherwise you'll return X twice
Returning the solution should be simple as return [X,Y]
So this can be simplified with a for (let i = 0; i < arr.length; i++) loop and a if statement with a return inside if the solution exist. This way, if a solution is found, the function won't loop further.
After that loop, you return [] because no solution were found.
EDIT:
Since you want a solution with map and filter:
findTwoPartsOfTheNumber = (arr, tNumber) => {
let solution = [];
arr.map((X, indexOfX) => {
const results = arr.filter((Y, indexOfY) => {
const add = Y + X
if (tNumber === add && indexOfX != indexOfY) return true;
else return false;
});
if (results > 0) solution = [X, results[0]];
})
return solution;
}

Categories

Resources