Could anyone help me do this task? I don't get how to do it.
I need to find the sum of this array using recursion.
[ 5,7 [ 4, [2], 8, [1,3], 2 ], [ 9, [] ], 1, 8 ]
I would probably be able to find the sum if it was a regular array, but this one here is a bit confusing having arrays within array.
It is pretty straightforward using recursion, just loop over the array and for each element check if it is another array, if so call the function on it and add its result to the sum, if not (meaning if it is a number) then just add the element to the sum, like so:
function sumArray(arr) { // takes an array and returns its sum
let sum = 0; // the sum
for(let i = 0; i < arr.length; i++) { // for each element in the array
if(Array.isArray(arr[i])) { // if the element is an array
sum += sumArray(arr[i]); // call the function 'sumArray' on it to get its sum then add it to the total sum
} else { // otherwise, if it is a number
sum += arr[i]; // add it to the sum directly
}
}
return sum;
}
BTW, the above code can be shortened drastically using the array method reduce, some arrow functions and a ternary operator instead of if/else like so:
const sumArray = arr => arr.reduce((sum, item) =>
sum + (Array.isArray(item) ? sumArray(item) : item)
, 0);
Sketch of the solution:
"The function" that calculates the total should do a regular loop over the array parameter.
For each element:
if it's a number then add it to the total (normal case),
but if it's an array, then add the result returned by "the function" applied on this inner array (recursive case).
I think this might be what you're looking for Recursion - Sum Nested Array
function sumItems(array) {
let sum = 0;
array.forEach((item) => {
if(Array.isArray(item)) {
sum += sumItems(item);
} else {
sum += item;
}
})
return sum;
}
One way to solve this is by breaking the array into two parts, calculating the sum of each part, and then adding the results.
For example, the implementation below separates the array into its first element and all the remaining elements. If the first element is an array, sum is recursively applied, otherwise the value is used directly. For the rest of the array, sum is recursively applied.
const sum = function(array) {
if (array.length === 0) return 0;
let first = array[0];
if (Array.isArray(first))
first = sum(first);
const rest = sum(array.slice(1));
return first + rest;
}
const array = [ 5, 7, [ 4, [ 2 ], 8, [ 1, 3 ], 2 ], [ 9, [] ], 1, 8 ];
console.log(sum(array)); // 50
Related
I've been trying to write a function which takes in an array as the first argument, then one or more other arguments which are numbers. The purpose of the function is to check whether these numbers are present in the array and remove them if so.
I have tried the following but the results haven't been what I had expected.
The desired outcome is that 3 and 2 be removed from the array leaving me with [1,4]. Instead, only 2 is removed with the end result being [1,3,4]. I've been struggling with this for a while and would appreciate any feedback you might be able to provide. I'm knew to this and this is the first problem which has left me stumped so far!
function test(myArray, ...checkNums) {
for (let num in checkNums) {
for (let num2 in myArray) {
if (myArray[num] == checkNums[num2]) {
myArray.splice(num, 1);
}
}
}
return myArray;
}
const arr = test([1, 2, 3, 4], 3, 2);
console.log({arr})
The easiest way is to just filter the array to only keep values not in checkNums. Using a Set gives better performance (depending on the implementation, lookup is either O(1) or O(log n) or anything sublinear for a Set, compared to O(n) for an Array).
function test(myArray, ...checkNums) {
const checkNumsSet = new Set(checkNums);
return myArray.filter((num) => !checkNumsSet.has(num));
}
const arr = test([1, 2, 3, 4], 3, 2);
console.log({arr})
With myArray and checkNums as arrays, you can use a filter based on .includes:
const myArray = [1,2,3,4];
const checkNums = [3,4];
const filterNums = (nums, checkNums) => {
return nums.filter(num => !checkNums.includes(num));
}
console.log(filterNums(myArray, checkNums));
Your code is removing items so your index variable is stale after you remove an element. The simplest fix is to just iterate backwards.
Also, you should avoid using for in to iterate over an array
Lastly, your array was just modifying what was passed in but you never kept a reference to it, I'm returning the modified array.
function test(myArray, ...checkNums) {
for (let checkNumsIndex = checkNums.length - 1; checkNumsIndex >=0; checkNumsIndex--) {
for (let myArrayIndex = myArray.length - 1; myArrayIndex >=0; myArrayIndex--) {
if (myArray[myArrayIndex] == checkNums[checkNumsIndex]) {
myArray.splice(myArrayIndex, 1);
}
}
}
return myArray;
}
const arr = test([1, 2, 3, 4], 3, 2);
console.log({arr});
A more straight forward is using filter and includes. This doesn't have the problem that your example has where you're testing values outside of the bounds of the array.
function removeElements(myArray, ...checkNums) {
return myArray.filter((num) => !checkNums.includes(num));
}
const arr = removeElements([1, 2, 3, 4], 3, 2);
console.log({arr});
You can use for...of see for..in vs for...of in order to iterate through your arguments, check if the number exist in your array and if yes, splice at index number
function test(myArray, ...checkNums) {
//get the elements from ...checkNums
for (let num of checkNums) {
//check if your number exist in array
if (myArray.includes(num)) {
const indexOfNum = myArray.indexOf(num);
//if it exists splice at found index of your umber
myArray.splice(indexOfNum, 1)
}
}
return myArray;
}
const result = test([1, 2, 3, 4], 3, 2);
console.log(result)
My current goal is to take items in array integers and create a key pair value based on how many times the key appeared in integers. My logic is: for i in integers, if i is in integers 2 already, increment that key's value by 1. if it doesn't exist, create the key and pair it with a value of 1. It's been a few hours now and after heavy googling I can't seem to find where im messing my logic up.
//require realdine-sync module
var readlineSync = require('readline-sync');
//initialize variable and list
var integer;
integers2 = {};
var integers = [];
//user input
integer = readlineSync.question('Integer?: ')
//check user input and append any integer besides 0
while (integer != 0 && integer >= 1 && integer <= 100){
console.log("not 0!")
integers.push(integer)
integer = readlineSync.question('Integer?: ')
}
console.log(integers);
for(i in integers){if (i in integers2){integers2[i] += 1}else{integers2[i] = 1}
}
console.log(integers2)
let integers2 = {}
integers = [5, 4, 5, 2, 4, 7, 5];
// you were using 'in' instead 'of', 'in': gives you index , 'of'?: gives you value of array
for (let i of integers) {
if (integers2[i]) { // if key exist increment value by one
integers2[i] += 1
} else { // else add 1 as the first value
integers2[i] = 1
}
}
console.log(integers2);
This is a solution that you can try which works. It uses the same logic as you described in the question. This solution uses Array.prototype.reduce() with a Map().
const howMany = arr => arr
.reduce(
(map, n) => map.set(n, (map.get(n) ?? 0) + 1),
new Map()
)
console.log([...howMany([3, 4, 6, 4, 5, 5, 5])])
I am trying to improve in my Problem Solving Skills and would love to get some explanation on what it is that I am doing wrong or if I can get a hand in the right direction. My code below is what I am stuck on.
My problem, I am trying to check within the array if it contains any numbers that will sum up to a total given value. Pretty simple but a bit complex for a beginner.
My first Step is to setup a function with two parameters that accept the array and total amount we want.
const array = [10, 15, 7, 3];
function sumUpTotal(array, total) {
}
Then I want to iterate through my array to check each value within the array by using the forEach method to output each value
const array = [10, 15, 7, 3];
function sumUpTotal(array, total) {
array.forEach(value => value)
}
Now that I have all the outputs, I am stuck on how I can check if the numbers add up with each other to give out the total we want. Can someone please help.
The Output should be two numbers that add up to the total.
For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.
Using forEach() to iterate over each value in the array and includes() to check if any values further ahead in the array sum to your total you can generate an array of unique sum pairs. By only looking forward from the given iteration one avoids generating duplicate pairings. (eg. avoids [[10, 7], [7, 10]] for you example input)
forEach() provides both the value and the index of the current iteration, which makes it simple to use the optional, second fromIndex argument of includes() to only look ahead in the array by passing index+1. If a match is found an array of [value, difference] is pushed to the result array. The return value is an array of sum pairs, or an empty array if there are no matches.
const array = [10, -2, 15, 7, 3, 2, 19];
function sumUpTotal(array, total) {
let result = []
array.forEach((value, index) => {
let diff = total - value;
if (array.includes(diff, index + 1)) result.push([value, diff]);
});
return result;
}
console.log(JSON.stringify(sumUpTotal(array, 17)));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do this using a Set as follows:
function sumUpTotal(array, total) {
// initialize set
const set = new Set();
// iterate over array
for(let i = 0; i < array.length; i++){
// get element at current index
const num = array[i];
// get the remaining number from total
const remaining = total - num;
// if the remaining is already stored in the set, return numbers
if(set.has(remaining)) return [num, remaining];
// else add number to set
else set.add(num);
}
// return null if no two numbers in array that sum up to total
return null;
}
const array = [10, 15, 7, 3];
const total = 17;
console.log( sumUpTotal(array, total) );
I have six integers stored in an array:
[2,3,4,5,6,7]
I would like to use each item in the array to check against a range of other integers 100 - 999 (i.e. all three-digit numbers) to find a number that has a remainder of 1 when divided by all the items in the array individually.
I'm not sure what javascript method to use for this. I'm trying a for loop:
function hasRemainder() {
let arr = [2,3,4,5,6,7];
for (i = 100; i < 999; i++) {
if (i % arr[0] == 1) {
return i;
}
}
}
but it has several problems I need to solve.
Instead of referring to a particular item e.g. arr[0], I need to find a way to loop through all the items in the array.
Currently, this function only returns one number (the loop stops at the first number with a remainder), but I need all the possible values in the given range.
If anyone could help with these two problems, I'd really appreciate it. Thanks.
You could map an array of values and then filter the array by checking every remainder value with one.
function hasRemainder() {
var array = [2, 3, 4, 5, 6, 7];
return Array
.from({ length: 900 }, (_, i) => i + 100)
.filter(a => array.every(b => a % b === 1));
}
console.log(hasRemainder())
This works also;
function hasRemainder() {
const arr = [2, 3, 4, 5, 6, 7];
const remainders = []
for (i = 100; i < 999; i++) {
const isRemainder = arr.every(numb => i % numb === 1)
if (isRemainder) {
remainders.push(i)
}
}
return remainders
}
So I need to solve this problem STRICTLY using recursion
// 2. Compute the sum of an array of integers.
// sum([1,2,3,4,5,6]); // 21
And then I'm testing this solution in PythonLive
var sum = function(array) {
if(array.length===0){
return array
}
return array.slice(0,array.length)+sum(array.pop())
};
sum([1,2,3,4,5,6]);
Then at step 6 it says "TypeError: array.slice is not a function"
I don't understand why if it already worked taking 6 off the array and returning the remaining array...
Can someone explain me what am I doing wrong please?
thanks! :)
If you look at the return values you will see that you are always returning an array. This can't be right when you want a number as a final result. When array.length === 0 you can safely return 0 because that's the same of an empty array. That's your edge condition. After that you just want the sum of one element plus the rest.
You can also just return the array length when it's zero making for a very succinct solution. && shortcircuits returning the left element if it's false (like 0) otherwise the second:
var sum = (array) => array.length && array.pop() + sum(array)
console.log(sum([1,2,3,4,5,6]));
If you prefer slice you could also this, which is basically the same:
var sum = (array) => array.length && array[0] + sum(array.slice(1))
console.log(sum([1, 2, 3, 4, 5, 6]));
Recursive sum function:
const sum = list => {
if (!list.length) return 0;
return list.pop() + sum(list);
};
Because .pop mutates the array, you don't need to use slice. For a non-destructive version (doesn't alter the original array):
const sum = ([first, ...rest]) => {
if (first === undefined) return 0;
return first + sum(rest);
};
The issue with your code is that you are processing the values the wrong way around, it should be
return sum(array.slice(0,array.length-1)) + array.pop();
In fact since array.pop() removes the element, you can just do it this way around:
return array.pop() + sum(array);
You also need to return 0 when array.length===0, otherwise the sum will fail.
if (array.length===0) return 0;
However it's much simpler just do this with reduce:
let arr = [1,2,3,4,5,6];
console.log(arr.reduce((t, v) => { return t + v; }, 0));
Another encoding using an explicit empty and pure expressions
const empty = x =>
x === empty
const sum = ([ x = empty, ...rest ]) =>
empty (x)
? 0
: x + sum (rest)
console.log
( sum ([ 1, 2, 3, 4, 5 ]) // 15
, sum ([]) // 0
)
Your other question that asks how to sum a nested array was put on-hold for reasons I don't understand. You can adapt the above implementation to support input of nested arrays
const empty = x =>
x === empty
const sum = ([ x = empty, ...rest ]) =>
empty (x)
? 0
: Array.isArray (x)
? sum (x) + sum (rest)
: x + sum (rest)
console.log
( sum ([ 1, [ 2, [ 3, 4 ], 5 ]]) // 15
, sum ([ 1, 2, 3, 4, 5 ]) // 15
, sum ([[[]]]) // 0
, sum ([]) // 0
)