I have an array named arr = [[1,2],4] , and for loops to access the numbers. But I can't seem to add the last number. Why is it not working?
let arr = [[1,2],4];
let total = 0;
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
total += arr[i][j];
}
}
console.log(arr.length) // returns length = 2
console.log(total); // returns total = 3
Your issue is that your array doesn't just consist of only arrays, it consists of both single numbers and nested arrays. As a result, your inner loop won't be able to loop over the number 4 as it is not an array (and so it won't have a .length property).
let arr = [[1,2],4];
// no issues-^ ^-- no `.length` property (inner for loop won't run)
For a problem like this, you can make use of a recursive function, which when you encounter a nested array, you can recall your function to perform the addition for that array.
See example below (and code comments):
function sumNums(arr) {
let total = 0;
for (let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) { // If current element (arr[i]) is an array, then call the sumNums function to sum it
total += sumNums(arr[i]);
} else {
total += arr[i]; // If it is not an array, then add the current number to the total
}
}
return total;
}
let arr = [[1,2],4];
console.log(sumNums(arr)); // 7
You can also make use of a recursive call with .reduce() if you would like to take that approach:
const arr = [[1,2],4];
const result = arr.reduce(function sum(acc, v) {
return acc + (Array.isArray(v) ? v.reduce(sum, 0) : v);
}, 0);
console.log(result); // 7
Since the values can be array or numbers, Just add the check before doing the inner loop
if (!Array.isArray(arr[i])) {
total += arr[i];
continue;
}
let arr = [[1,2],4];
let total = 0;
for(let i = 0; i < arr.length; i++) {
if (!Array.isArray(arr[i])) {
total += arr[i];
continue;
}
for(let j = 0; j < arr[i].length; j++) {
total += arr[i][j];
}
}
console.log(arr.length) // returns length = 2
console.log(total);
Related
I have an array of numbers. I need to find the maximum number of consecutive 1s in the array.
var arr = [1, 1, 3, 2, 3, 1, 1, 1];
const maxOne = (arr) => {
for (var i = 0; i < arr.length; i++) {
let count = 0;
let result = 0;
if (arr[i] ==1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
return result
}
}
console.log(maxOne(arr));
desired output: 3
my output : 1
I am not sure where I am going wrong
You algorithm works, you just did few misstakes:
create variables outside of loop
return after loop, not in it(it will break loop at first iteration)
const maxOne = (arr) => {
let count = 0;
let result = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] === 1) {
count += 1;
result = Math.max(result, count);
} else {
count = 0
}
}
return result
}
You can do like this.
let arr=[1,2,3,1,1,2,1,1,12,1,1,1,1];
let count=0;
for(let i=0;i<arr.length;i++){
arr[i]==1 ? count+=1 :count=0;
}
console.log(count).
const numbers = [1,1,0,0,1,1,1,0,1];
const maxString = Math.max(...numbers.join('').split('0')); // remove zero items and convert
// the sequential Ones to a string. After that Find the string with the largest number of characters.
console.log('max:', maxString.toString().length) // Take the string length
//3
you can use *Math.max.apply(Math, numbers.join('').split('0'))* instead of second line.
So the problem is given an array we have to find the maximum possible sum among:
all nonempty subarrays.
all nonempty subsequences.
Example:
arr = [-1,2,3,-4,5,10]
The maximum subarray sum is comprised of elements at inidices [1-5] Their sum is 2+3+-4+5+10 =16 The maximum subsequence sum is comprised of elements at indices [1,2,4,5] and their sum is [2,3,5,10] = 20
I tried solving this.. But for large arrays (for lengths > 50k) I am getting an error "Abort Called".
What is the reason behind this error?! Is it that my code isn't optimised?
function maxSubarray(arr) {
let subsequenceSum = 0
for (let i = 0; i < arr.length; i++) {
if (arr[i] < 0 ) continue
else subsequenceSum += arr[i]
}
if (!subsequenceSum) {
subsequenceSum = Math.max(...arr)
}
const allsubArrays = []
const sumOfEachSubArr = []
for (let i = 0; i < arr.length; i++) {
for (let j = i ; j < arr.length; j++) {
const tempArr = arr.slice(i, j+1)
allsubArrays.push(tempArr)
}
}
// Getting sum of all subarrays
for (let subArr of allsubArrays) {
let sum = subArr.reduce((sum, curVal) => {
return sum + curVal
}, 0)
sumOfEachSubArr.push(sum)
}
let subArraySum = Math.max(...sumOfEachSubArr)
const result = []
result.push(subArraySum,subsequenceSum )
console.log(result)
return result
}
I have written a function and called another function inside but my tests show that it is not time optimized. How can I make the following code faster?
function maxSum(arr, range) {
function sumAll(array1, myrange) {
var total = 0;
if (Array.isArray(myrange)) {
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
return total;
} else return array1[myrange];
}
var mylist = [];
var l = range.length;
for (var n = 0; n < l; n++) {
mylist.push(sumAll(arr, range[n]));
}
return Math.max.apply(null, mylist);
}
Algorithmic optimization: create new array with cumulative sums from index 0 to every index
cumsum[0] = 0;
for (var i = 1; i <= arr.Length; i++) {
cumsum[i] = cumsum[i-1] + arr[i-1]
Now you don't need to calculate sums for every range - just get difference
sum for range (i..j) = cumsum[j+1] - cumsum[i];
in your terms:
function sumAll(array1, myrange) {
return cumsum[myrange[1]+1] - cumsum[myrange[0]];
}
example:
arr = [1,2,3,4]
cumsum = [0,1,3,6,10]
sum for range 1..2 = 6 - 1 = 5
P.S. If your array might be updated, consider Fenwick tree data structure
1) You can define the function sumAll outside of the function maxSum because every time you call maxSum the javascript engine is recreating a fresh new function sumAll.
2) You can define myrange[1] as a variable in the initialiser part to avoid javascript to look for myrange[1] at each iteration.
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
become this:
for (var i = myrange[0], len = myrange[1]; i <= len; i++) {
total += array1[i];
}
Full working code based on #MBo's excellent optimization. This passes all the tests at https://www.codewars.com/kata/the-maximum-sum-value-of-ranges-challenge-version/train/javascript, which I gather is where this problem comes from.
function maxSum(arr, ranges) {
var max = null;
var sums = [];
var sofar = 0;
for (var i = 0; i <= arr.length; i++) {
sums[i] = sofar;
sofar += arr[i];
}
for (var i = 0; i < ranges.length; i++) {
var sum = sums[ranges[i][1]+1] - sums[ranges[i][0]];
if (max === null || sum > max) {
max = sum;
}
}
return max;
}
when I run this program I end up with NaN at the end; I'd appreciate some form of explanation, as I'm stumped! I have an odd feeling it has to do something with scope...
https://jsfiddle.net/Smuggles/evj46a23/
var array = []
var range = function(start, end) {
for (var count = start; count <= end; count++) {
array.push(start);
start += 1;
}
console.log(array);
}
var sum = function() {
var result = 0
var arrayLength = array.length
for (var count = 0; count <= arrayLength; count++) {
result += array[count]
console.log(result);
}
}
console.log(sum(range(1, 10)));
2 things:
You need to change the for loop in the sum function to be < arrayLength and not <= arrayLength. You are dealing with array lengths which start with a 0 index.
You need to return the result from the sum function
var array = [];
var range = function(start, end) {
for (var count = start; count <= end; count++) {
array.push(start);
start += 1;
}
};
var sum = function() {
var result = 0;
var arrayLength = array.length;
for (var count = 0; count < arrayLength; count++) {
result += array[count];
}
return result;
};
console.log(sum(range(1, 10)));
Given an array of [4,5,6], the indexes would be as follows:
0: 4
1: 5
2: 6
Therefore, when you use the length property of the array (3), you are referencing an index that does not exist, which returns undefined. It tries to do the math on the undefined, which causes a NaN. This is why you have to use < arrayLength.
The functional approach:
It would help to make those functions a bit more "pure". Instead of maintaining state outside of the functions (with var array = []), just return the values from the functions: See the following for example:
function range(start, end) {
var arr = [];
for (var i = start; i <= end; i++) {
arr.push(i);
}
return arr;
}
function sumArray(array) {
return array.reduce(function(a, b) {
return a + b;
});
}
console.log(sumArray(range(1, 10)));
Each function takes arguments, and simply returns the result. This way, you approach this a little more "functional".
Description in Comments of Code
var array = [];
var range = function(start, end) {
//simplified the loop to remove unnecessary variables
for (; start <= end; start++) {
array.push(start);
}
return array;
}
var sum = function() {
var result = 0;
// move length to scope of the loop
// change to < rather than <= due to zero index nature of arrays
for (var count = 0, length = array.length; count < length; count++) {
result += array[count];
}
// return the result from the function
return result;
}
// gets an array from 1-10
var arr = range(1, 10);
// print the array to the console
console.log(arr);
// print the sum to the console
console.log(sum(arr));
as the title says i'm trying to sum up using a for loop to iterate over an array.
can you give me some pointers as to where i'm going wrong here. i am returning the value NaN.
var total = 0;
function sum(input) {
for (idx=0; idx<=input; idx++) {
total += input[idx];
}
return total;
}
You actually don't need a loop to do this in modern browsers, you can use the Array.reduce function:
var sum = input.reduce(function(a,b){
return a+b;
}, 0);
You need ot declare total into function and also you need to declare idx. Another thing that instead of writing idx <= input.length you have to write idx <= input.length - 1. Since last index will be undefined.
Try
function sum(input) {
total = 0;
for (var idx = 0; idx <= input.length - 1; idx++) {
total += input[idx];
}
return total;
}
variable total is not declared!
function sum(input) {
var total = 0;
for (idx=0; idx <= input.length; idx++) {
total += input[idx];
}
return total;
}
You are using input both as an integer, and as an array of values. Probably you mean for( var idx = 0; idx < input.length; ++idx )....
Problem which result in NaN is because of your array traversing array till end, rather than from indices 0 to input.length-1
Try this:
http://jsfiddle.net/t9tfofxv/
var total = 0;
function sum(input) {
for (var idx=0; idx< input.length; idx++) {
total += input[idx];
}
return total;
}
var s=sum([1,2,3,4]);
alert(s);
Declare the variable total inside the function, and also use input.length-1 to define the loop's range:
function sum(input) {
var total = 0;
for (idx=0; idx <= input.length-1; idx++) {
total += input[idx];
}
return total;
}