I tried to recursion those arrays to find odd/even numbers then push them to newArr but the result, not an array, that result is the string with numbers the result after found the odd/even numbers.
this is the code i wrote,
function odd(nums){
var result = [];
if(nums.length === 0) {
return result;
} else if (nums[0] % 2 === 0){
result.push(nums[0])
// return odd(nums.slice(1))
};
return result + odd(nums.slice(1));
};
var arr = [1,8,3,4,4,5,9,13,13,9,10];
var print = odd(arr);
console.log(print)
if i don't write return result + odd(nums.slice(1)); the result nothing / undefined,
can anyone help me to explain why that result in a string, not an array I wanted
You need to concat arrays. + does only work for strings or for numbers.
BTW, after block statements { ... }, you do not need a semicolon.
function odd(nums){
var result = [];
if (nums.length === 0) {
return result;
}
if (nums[0] % 2 === 0) {
result.push(nums[0]);
}
return result.concat(odd(nums.slice(1)));
}
var arr = [1, 8, 3, 4, 4, 5, 9, 13, 13, 9, 10];
var print = odd(arr);
console.log(print);
Recursion is probably a bad idea in JS, you should use it unless there is no better way to solve a problem. It will be slower and possibly result in overflow, if too many calls of recursive function is made.
To get the result you needed, it is better to use array filter method. It is clearer and faster.
var arr = [1,8,3,4,4,5,9,13,13,9,10];
var odd = arr.filter(n => !(n % 2))
console.log(odd)
As for the original question, I'd do it this way:
function odd(nums, result = []){
if (!nums.length) return result; // no need for else, this way clearer
if (nums[0] % 2 === 0) result.push(nums[0])
return odd(nums.slice(1), result)
};
var arr = [1,8,3,4,4,5,9,13,13,9,10];
console.log(odd(arr))
!!! Caution, next snippet WILL result in StackOverflow !!!
You may decrease array length to 10000 to check that it will work just fine.
function odd(nums, result = []){
if (!nums.length) return result; // no need for else, this way clearer
if (nums[0] % 2 === 0) result.push(nums[0])
return odd(nums.slice(1), result)
};
const arr = Array.from({length: 100000}, (_,i) => i)
const result = odd(arr)
console.log(`Array length: ${arr.length}`)
console.log(`Result length: ${result.length}`)
console.log(result.slice(0,5))
You could use concat method.
function odd(nums){
var result = [];
if(nums.length === 0) {
return result;
} else if (nums[0] % 2 === 0){
result.push(nums[0])
// return odd(nums.slice(1))
}
return result.concat(odd(nums.slice(1)));
}
var arr = [1,8,3,4,4,5,9,13,13,9,10];
var print = odd(arr);
console.log(print)
Another approach would be to pass the array containing the result as parameter, since it will be a reference, you don't have to return anything.
function odd(nums, result)
{
if(nums.length != 0)
{
if (nums[0] % 2 === 0)
{
result.push(nums[0]);
}
odd(nums.slice(1), result);
}
}
var arr = [1,8,3,4,4,5,9,13,13,9,10];
var result = [];
odd(arr, result);
console.log(result)
Instead of the concat you need in place of the string concatenation + you use now, better use filter
var odd = [],
even = [1,8,3,4,4,5,9,13,13,9,10]
.filter(function(x) { if (x % 2 === 0) return true; else odd.push(x) } );
console.log(odd,even)
Related
I have written a simple JavaScript code to print the max number of an array and get undefined printed as well.
let arrNums = [1,2,5,19,20];
const maxNum = function(arr) {
if (arr.length != 0) {
console.log(Math.max(...arr));
}
else{
console.log("Empty");
}}
console.log(maxNum(arrNums));
Your function doesn't return anything. Return the Math.max() and the 'Empty' for it to work. After that you can just use console.log(maxNum(arrNums)); outside the function. See below for an example of this:
const arrNums = [1, 2, 5, 19, 20];
const maxNum = function (arr) {
if (arr.length != 0) {
return Math.max(...arr);
} else {
return 'Empty';
}
}
console.log(maxNum(arrNums));
Hoped this helped!
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;
}
I am trying to write a function to save all the digits of any given number in an array by using the recursive method, but it stops at the first digit and the looping is no work, can someone tell me what I did wrong?
function digit(n) {
var arr = [];
if (n < 10) {
return arr.push(n);
} else {
var dig = n % 10;
arr.push(dig);
digit(Math.floor(n / 10));
}
return arr;
}
Because you reset arr to an empty array each time, it never gets anywhere. You need to store it outside the recursive function and return it at the end.
function digit(d) {
var arr = [];
function store_digit(n) {
if (n < 10) {
return arr.push(n);
} else {
var dig = n % 10;
arr.push(dig);
store_digit(Math.floor(n / 10));
}
}
store_digit(d);
console.log(arr)
return arr;
}
digit(682)
The code is running through all the digits. Since you are initializing the array each time your function runs, it's just returning the last run digit.
Try this one:
var arr = [];
function digit(n) {
if (n < 10) {
return arr.push(n);
}
else {
var dig = n % 10;
arr.push(dig);
digit(Math.floor(n / 10));
}
}
digit(123456789)
console.log(arr)
recursion is correct but you are not using the returned values correctly, you will only return the last digit the way you are doing, you need to concat arrays returned from the successive method calls. something like this seems to work:
function digit(n){
var arr = [];
if(n<10){
arr.push(n);
}else{
var dig = n % 10;
arr.push(dig);
arr = arr.concat(digit(Math.floor(n /10)));
}
return arr;
}
console.log(digit(999));
digit(123456);
function digit(n) {
var arr = [];
if (n < 10) {
arr.push(n);
} else {
numberToString = n.toString();
for (var i = 0, len = numberToString.length; i < len; i += 1) {
arr.push(+numberToString.charAt(i));
}
console.log(arr);
}
}
All the answers given so far have got the right idea. Here's that idea expressed a little more simply:
function digits(n, result=[]){
return n < 10
? result.concat([n]).reverse()
: digits(Math.floor(n / 10), result.concat([n % 10]);
}
digits(1234); //=> [1, 2, 3, 4]
You can remove the .reverse() if the expected output goes smallest order to greatest order rather than greatest to smallest.
demo
You could use a clean approach, where every call of the function returns a valid part result.
At start you define the recursion temination, which is given if the value of n is smaller than 10. In this case you return an array with the value.
In all other cases, you return the result of the recursion call of the integer value of n divided by 10 and concat the rest of a division by 10.
This proposal does not use another explicit temporary variable.
function getDigits(n) {
if (n < 10) {
return [n];
}
return getDigits(Math.floor(n / 10)).concat(n % 10);
}
console.log(getDigits(123456));
For a more concise style, you could use a ternary with the same idea as above.
function getDigits(n) {
return n < 10 ? [n] : getDigits(Math.floor(n / 10)).concat(n % 10);
}
console.log(getDigits(123456));
Using the spread operator:
function getDigits(num, radix = 10) {
return num < radix ?
[num] :
[...getDigits(Math.floor(num / radix), radix), (num % radix)];
}
getDigits(0xCAFEBABE, 0x10);
// ==> [12, 10, 15, 14, 11, 10, 11, 14]
Code:
var arr = [];
function digit(n){
if (n<10) {
return arr.push(n);
} else {
var dig = n % 10;
arr.push(dig);
digit(Math.floor(n /10));
}
return arr;
}
I'm trying to use the reduce() method to find one skipped (missing) number in an array of (sometimes almost) consecutive numbers. Only one number will be missing at most.
This is my codepen: http://codepen.io/PiotrBerebecki/pen/zBrRVd
For example,
findMissing([1,2,3,5]) should return 4
findMissing([1,2,3,4]) should return undefined
findMissing([2,3,4,6]) should return 5
findMissing([2,4,5,6]) should return 3
The code that I developed seems to work fine if there is indeed a number that was skipped. But it returns an undesired value if all numbers are present. Would you know how to fix it?
My JS code:
function findMissing(arr) {
return arr.reduce(function(prev, curr) {
if (curr - prev !== 1) {
return curr - 1;
}
});
}
// This should return 4, and it indeed returns 4
console.log( findMissing([1,2,3,5]) );
// This should return 'undefined', but it returns 3
console.log( findMissing([1,2,3,4]) );
// This should return 5, and it indeed returns 5
console.log( findMissing([2,3,4,6]) );
UPDATE 1:
Based on the answers below, the following code delivers the desired outcome using the reduce() method:
// ****SOLUTION:****
function findMissing2(arr) {
return arr.reduce(function(prev, curr, index, array) {
if (curr === index + array[0]) {
return prev;
} else {
return index + array[0]++;
}
}, void 0);
}
console.log( findMissing2([1,2,3,4]) ); // Undefined
console.log( findMissing2([1,2,3,5]) ); // 4
console.log( findMissing3([2,3,4,6]) ); // 5
console.log( findMissing2([2,3,4,5]) ); // Undefined
console.log( findMissing2([2,4,5,6]) ); // 3
I would do this job as follows;
var a1 = [1,2,3,5],
a2 = [2,3,4,5],
a3 = [2,4,5,6],
res1 = a1.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0),
res2 = a2.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0),
res3 = a3.reduce((p,c,i,a) => c == i+a[0] ? p : i + a[0]++, void 0);
console.log(res1);
console.log(res2);
console.log(res3);
Note: void 0 is a very safe undefined value in JS. The above code will mutate the tested array. You might prefer to call like a1.slice().reduce... if you want to keep the tested array as it is.
Instead of reduce you should use for loop here
function findMissing(arr) {
var r = [];
for (var i = arr[0]; i <= arr[arr.length - 1]; i++) {
if (arr.indexOf(i) == -1) r.push(i);
}
return r;
}
console.log(findMissing([1, 2, 3, 5]));
console.log(findMissing([1, 3, 6]));
console.log(findMissing([10, 13, 16]));
Your reduce closure/callback function needs to return the value to be used as the next prev in the next iteration.
Because of this, in the second example, the first iteration returns undefined, as it does not enter the if block. The second iteration is passed the parameters of undefined, 3, where undefined - 3 !== 1 so it returns 2.
This propagates the way up your iterations, until it returns 3.
As such, I'm struggling to think of a way your reduce function could be adapted to correct this.
Perhaps using a simple for loop might be a bit more robust?
function findMissing(arr) {
for(var i = 1; i < arr.length; i++) {
if(arr[i] - arr[i-1] !== 1) {
return arr[i]-1;
}
}
}
As I said in comments, if you are looking for efficiency you could do it with recursion:
function findMissing(arr) {
if (arr.length === 1) return;
if(arr[1] - arr[0] !== 1){
return arr[0];
}
else{
return findMissing(arr.slice(1,arr.length));
}
}
Or even with a while loop:
function findMissing(arr) {
var i = 0;
while (arr[i+1] - arr[i] === 1) {
i++;
}
if (i < arr.length-1) return arr[i];
}
var findMissing = function (list) {
var expected_sum = (list[0] + list[list.length - 1]) * (list.length + 1) / 2;
var sum = list.reduce((a,b)=>a+b);
return expected_sum - sum;
}
console.log(findMissing([-5,-1,1,3,5,7,9,11]))
I am trying to evaluate an array for uniformity. I.e. var num =[1,1,1,1,1,] // true or var num =[1,1,2,1,1] = //false. It could also be for an array of strings. What I am trying to do is evaluate the whole array and return a single "true" or "false". My code so far evaluates each item in the array and returns the result for each item. I'm very new to coding and taking classes online and working through problems without cheating!
var num = [1,1,3,1,1];
var first = num[0];
num.forEach(function (num, i) {
if(first === num){
console.log(true);
} else {
console.log(false);
}
});
You're on the right track. Instead of logging a true or false for each answer, create a variable to store the overall answer, then print that when you're done. Something like this:
var num = [1,1,3,1,1];
var first = num[0];
var ans = true;
num.forEach(function (n) {
if(first !== n){
ans = false;
}
});
console.log(ans);
Using .some()
var num = [1,1,3,1,1];
var notUni = num.some(function(val, idx, arr){
return val != arr[0]; // (If arr[0] (1) is the base you're interested in)
});
console.log( notUni ); // true
P.S: some will exit as soon it finds a (true) mismatch.
Use Array.prototype.every() function
var num = [1, 1, 3, 1, 1];
var result = num.every(n => n == num[0]);
The every() method tests whether all elements in the array pass the test implemented by the provided function.
var num = [1, 1, 1, 1, 1];
var result = num.every(n => n == num[0]);
document.write(result);