Sum of elements in array using recursion even if they are string - javascript

Have to create a function that return the sum of the element in the array but if the array is
["a","b","c"] // output : abc
So far I have
function calculateSumRecursion(array) {
//your code
if (array.length === 0 ) {
return 0
}
return array[0] + calculateSumRecursion(array.slice(1))
}
I found out how to calculate the sum of all numbers using recursion but when it's an array of string like
array = ["a","b","c"]
it returns me
// abc0
because of the if statement.. is there any way to say
if (array.length === 0) return nothing instead of a 0 (that work only when it's an array of number?)

You just need to return the only value in the array when the length is 1, rather than waiting until you get a length of 0. That way you are always summing compatible types (numbers or strings). Note that you still need a test for a 0 array length in case the function gets called with an empty array. In this case you need to choose what to return; as requested, it is 0.
function calculateSumRecursion(array) {
if (array.length === 0) {
return 0;
}
if (array.length === 1) {
return array[0];
}
return array[0] + calculateSumRecursion(array.slice(1))
}
console.log(calculateSumRecursion([1, 2, 3, 4, 5]));
console.log(calculateSumRecursion(['a', 'b', 'c']));
console.log(calculateSumRecursion([]));

let arr = [1,2,3,4,5] // output : abc
let sum = calculateSumRecursion(arr);
function calculateSumRecursion (arr) {
return arr.length ? arr.pop() + calculateSumRecursion(arr) : 0;
}
Slice version
let arr = [1,2,3,4,5] // output : abc
let sum = calculateSumRecursion(arr);
function calculateSumRecursion (arr) {
return arr.length ? arr[0] + calculateSumRecursion(arr.slice(1)) : 0;
}

Change return 0 to return "" which will add an empty string to the sum.

You have returned 0 when the array is empty.
Now, you are doing string operations so it is needed to return empty value (not zero) so it will be affordable to return "".
function calculateSumRecursion(array) {
return array.length === 0 ? "" : array[0] + calculateSumRecursion(array.slice(1));
}

There's a way easier way to do this:
function calculateSumRecursion(array) {
var out = array[0];
for (let i = 1; i < array.length; i++) {
out = out + array[i];
}
return out;
}

Return empty string on recursion base case. Just replace your return 0 to return ''.
const array = ['a', 'b', 'c'];
function calculateSumRecursion(array) {
if (array.length === 0) {
return '';
}
return array[0] + calculateSumRecursion(array.slice(1));
}
console.log(calculateSumRecursion(array));
If you are want to work with number also then check array length for zero as well as one.
const array = ['a', 'b', 'c', 'e'];
const array2 = [];
const array3 = [1, 2, 3];
function calculateSumRecursion(array) {
const rec =
array.length === 1
? array[0]
: array.length >= 1 && array[0] + calculateSumRecursion(array.slice(1));
return array.length === 0 ? 0 : rec;
}
console.log(calculateSumRecursion(array));
console.log(calculateSumRecursion(array2));
console.log(calculateSumRecursion(array3));

Related

Count of values in javascript

I have homework to write a function that will be called with 2 parameters:
a is a list of numbers.
amount represents the count of the numbers in the array.
The function should return the number in the list that occurs amount times.
For example , if a = [5,5,5,3,2,1,1], and amount = 2, the function should return 1, because there are only two ones in the array. If amount = 3, the function should return 5 , if amount = 6, the function will return 0 since there are numbers that occur six time.
try this one
var max=3;
var array=[5,5,5,3,2,1,1];
console.log(verify(array,max))
function verify(array,max) {
var match=0;
array.map(obj => {
if(array.filter(x => x === obj).length == max)
match= obj;
});
return match;
}
Here is a way to get the values by count using reduce.
Since there may be more than one element matching the count, or even 0, an array is returned.
reduce is used to build a map (object) of the unique items to their counts. We the find the map entries where the counts match, and the keys (unique items) for these entries are returned.
const count = (arr, num) => {
const count = arr.reduce((count, x) => {
count[x] = (count[x] || 0) + 1;
return count;
}, {});
return Object.entries(count)
.filter(([k, v]) => v === num)
.map(([k, v]) => +k);
}
console.log(count([5,5,5,3,2,1,1], 1)); // [2, 3]
console.log(count([5,5,5,3,2,1,1], 3)); // [5]
console.log(count([5,5,5,3,2,1,1], 5)); // []
make a array of unique values from real array. Then loop though it and filter() real array to check the count of elements.
const array = [5,5,5,3,2,1,1]
function count(arr,amount){
const unique = [...new Set(arr)];
for(let item of unique){
if(arr.filter(num => num === item).length === amount)
return item;
}
return 0;
}
console.log(count(array,1));
console.log(count(array,2));
console.log(count(array,3));
console.log(count(array,4));
console.log(count(array,5));
You should use below code.
#RaviTeja's code is giving max number of array but you dont want it. You want to number which is same quantity with your "amount" parameter.This code provides this for you
function findingAmount() {
var numberContainer = [ 2, 3, 2,5,2,3 ];
console.log(findingAmountImp(numberContainer,1)); // result 5
console.log(findingAmountImp(numberContainer,2)); // result 3
console.log(findingAmountImp(numberContainer,3)); // result 2
}
function findingAmountImp(numbers,amount) {
var count=1;
for (i=0; i<numbers.length; i++) {
for (j=0; j<numbers.length; j++) {
if(i===j){
j=j+1;
if(j<numbers.length){
if(numbers[i] === numbers[j])
{
count++;
}
}else{
for(k=0;k<i;k++){
if(numbers[i] === numbers[k])
{
count++;
}
}
}
}else{
if(numbers[i] === numbers[j])
{
count++;
}
}
}
if( count === amount){
return numbers[i]
}
count=1;
}
}

Test If The Array Index Equals The Array Value

The code is to return the lowest index in an array when the value in the array is the same as the index. If there are no matches i should return -1. For example:
indexEqualsValue([-8,0,2,5])
output: 2 //array[2] == 2
indexEqualsValue([-1,0,3,6])
output: -1 //no matches
The code works when there are no matches or if the length of the array is zero, but not at other times. I think the problem is the first condition in my if statement. I don't necessarily want an answer, more tips on what I should check/rewrite.
Thanks!
function indexEqualsValue(a) {
return a.reduce((acc, currV, currI) => {
if (currI === currV) {
return currV;
}
return -1;
}, 0);
}
You could just find the index with Array#findIndex.
const indexEqualsValue = array => array.findIndex((v, i) => v === i);
console.log(indexEqualsValue([-8, 0, 2, 5])); // 2
console.log(indexEqualsValue([-1, 0, 3, 6])); // -1
some exits when it matches, so you can use it to quickly find what you need:
const indexEqualsValue = array => {
let match;
const didMatch = array.some((v, i) => {
match = i;
return v === i;
})
return didMatch ? match : -1;
}
console.log(indexEqualsValue([-8,0,2,5]))
console.log(indexEqualsValue([-8,0,2,5,0]))
console.log(indexEqualsValue([-1,0,3,6]))
nina-scholz's answer is better, the only advantage of using some over findIndex is that some is supported in ie whereas it seems findIndex is not.
for(i = 0,c=0;i < arr.length; i++ ) {
if(arr[i] == i) {
c = 1;
break;
}
}
if( c == 0 ) {
print(c);
} else {
print (i);
}

Mixed Element Small Number - JS

Hi I am creating a function that returns the smallest number within the given array. If the array contains no numbers, it should return 0.
Here's my function:
function findSmallestNumberAmongMixedElements(arr){
if(arr.length === 0 && typeof arr === 'string'){
return 0;
} else{
return Math.min.apply(null, arr); //min=1
}
}
var output = findSmallestNumberAmongMixedElements([4, 'lincoln', 9, 'octopus']);
console.log(output); // --> 4
Right now my answer return NAN instead of 4. Do you have any idea what am I doing wrong?
typeof arr === "string" will always be false if you are passing an array (wether or not the array contain strings is irrelevant for that test).
What you should do is first, filter the numbers out of the array using filter, then call Math.min on the filtered array:
function findSmallestNumberAmongMixedElements(arr) {
var onlyNumbers = arr.filter(e => typeof e === "number"); // filter out only items that are numbers
if(onlyNumbers.length === 0) return 0; // if there is no numbers, return 0
return Math.min.apply(null, onlyNumbers); // otherwise return the min of them
}
var output = findSmallestNumberAmongMixedElements([4, 'lincoln', 9, 'octopus']);
console.log(output); // --> 4
Your current function may produce NaN when you try to apply Math.min to an input array which contains both string and number values. Math.min can only handle numeric inputs, so the presence of a string may cause it to return the NaN error value.
There is a simple solution: filter out all of the non-number values from the array. We can check the length of the filtered array to see if there were any non-numeric values and, if so, apply Math.min without worry.
function findSmallestNumberAmongMixedElements(arr) {
var filtered = arr.filter(function(el) {
return typeof el == 'number';
});
if (filtered.length > 0) {
return Math.min.apply(Math, filtered);
} else {
return 0;
}
}
[
[4, 'lincoln', 9, 'octopus'], // 4
[], // 0
['a', 3, 2], // 2
['h', 'i'], // 0
['-3', 3], // 3
].forEach(function(input) {
console.log(input, findSmallestNumberAmongMixedElements(input));
});
In your Math.min.apply(null, arr), you are getting NaN because there are strings in the array.
Your typeof arr === 'string' does not loop through your array to exclude string value within the array.
What you need to do to achieve your goal is to probably just do a for loop or forEach loop:
function findSmallestNumberAmongMixedElements(arr){
var min = Infinity;
// if argument is not array or array has no value
if (arr.constructor !== Array || arr.length === 0){
min = 0;
return min;
}
/* for loop */
for (var i = 0, len = arr.length; i < len; i++){
if (arr[i] === 0 || typeof arr[i] !== 'number') continue;
min = Math.min(min, arr[i]);
}
/* forEach loop */
arr.forEach(function(value, index){
if (value === 0 || typeof value !== 'number') return;
min = Math.min(min, value);
});
return min;
}
var output = findSmallestNumberAmongMixedElements([4, 'lincoln', 9, 'octopus']);
console.log(output); // --> 4
I think you should filter your array before giving it to Math.min
Try the following
function isNumber (obj) {
return obj!== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
function smallestInMixedArray (arr) {
if (arr.length === 0 || !arr.filter) {
return 0;
} else {
arr = arr.filter(isNumber)
return Math.min.apply(null, arr); //min=1
}
}
var output = smallestInMixedArray([4, 'lincoln', 9, 'octopus']);
console.log(output); // --> 4

Use reduce() method to find a skipped number in an array of consecutive numbers

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]))

Finding the sum of a nested array

I tried finding the sum of all numbers of a nested array, but I don't get it to work correctly. This is what I tried:
function arraySum(i) {
sum = 0;
for (a = 0; a < i.length; a++) {
if (typeof i[a] == 'number') {
sum += i[a];
} else if (i[a] instanceof Array) {
sum += arraySum(i[a]);
}
}
return sum;
}
When you try it out with the array [[1,2,3],4,5], it gets 6 as the answer, instead of 15.
Does somebody know where there is a mistake in it?
The problem with your code is that the sum and a variables are global, instead of local. Because of this you get an infinite loop (a from the first entry in the function is reset by the second entry, so the same elements are processed again).
Fix it by adding var to where sum and a are declared to make them local to the function:
function arraySum(i) {
var sum=0; // missing var added
for(var a=0;a<i.length;a++){ // missing var added
if(typeof i[a]=="number"){
sum+=i[a];
}else if(i[a] instanceof Array){
sum+=arraySum(i[a]);
}
}
return sum;
}
Demo: http://jsbin.com/eGaFOLA/2/edit
I know it's late, but they say "is never late" :)
const sumNestedArray = arr => arr.flat(Infinity).reduce((a,b)=> a+b, 0)
const sumNestedArray = arr => arr.flat(Infinity).reduce((a,b)=> a+b, 0)
console.log(sumNestedArray([1,[2], [2, 3, [4]]]))
sumNestedArray([1,[2], [2, 3, [4]]])
For 2018 this solution is clean and functional:
let arr = [[ 1, 2, 3], 4, 5]
arr.flat().reduce((d, i) => d + i)
Documentation for flat and reduce.
Recurse, for example
function arraySum(x) {
var sum = 0, i;
if (typeof x === 'number')
return x;
else if (x instanceof Array)
for (i = 0; i < x.length; ++i)
sum += arraySum(x[i]);
return sum;
}
arraySum([[1,2,3],4,5]); // 15
I didn't optimise this so that it's clear, you may want some more logic before recursion.
The reason yours isn't working is because you need to var both sum and a.
You're missing two var in there. You've implicitly declared sum and a at window scope:
function arraySum(i) {
**var** sum=0;
for(**var** a=0;a<i.length;a++){
if(typeof i[a]=="number"){
sum+=i[a];
}else if(i[a] instanceof Array){
sum+=arraySum(i[a]);
}
}
return sum;
}
First of all why you use 'i' as input to function? we using 'i' to denote running index..
Regarding your question,you want 'a' to be local in your loop so instead of "for(a=0;..." instead write "for(var a=0;"
<html>
<body>
<script>
function NestedArraySummation(arr)
{
var sum=0;
for(var i=0;i<arr.length;i++)
{
if(typeof arr[i]=="number")
sum=sum+arr[i];
else if(arr[i] instanceof Array)
sum=sum+NestedArraySummation(arr[i]);
}
return sum;
}
var MyArray=[1,[2,3],4,10,[1,2]];
var Sum=NestedArraySummation(MyArray);
document.write(Sum);
</script>
</body>
</html>
This can be done with lodash _.flattenDeep and _.sum:
const arr = [[1, 2, 3], 4, 5];
arraySum(arr);
function arraySum(arr) {
var arrFlattens = _.flattenDeep(arr);
// => [1, 2, 3, 4, 5]
console.log(_.sum(arrFlattens));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Here you go:
(My assumption is that you want to parse strings, e.g., '13', into numbers in order include them in the sum. If not, just change isNumber to typeof val === 'number'.
function arraySum(arr) {
let sum = 0;
while (arr.length) {
const val = arr.pop();
const isArray = typeof val === 'object' && val.length !== undefined;
const isNumber = !isArray && !isNaN(sum + parseFloat(val));
if (isArray && val.length) {
sum += arraySum(val);
}
else if (isNumber) {
sum += parseFloat(val);
}
}
return sum;
}
console.log(arraySum([])); //0
console.log(arraySum([1, 1, 1, [3, 4, [8]], [4]])); //22
console.log(arraySum([1, 1, [], {}, 'l', 1, [3, 4, [8]], [4]])); //22
This was posted long ago but it might help others. I did the following and it seems to be working just fine
function countArray (array) {
//iterate through the array
for(let i = 0;i < array.length; i++){
//check if element of array is an array, and if it is, run method flat() to the whole array.
if(Array.isArray(array[i])){
array = array.flat()
}
}
//return the sum of the elements of the array
return array.reduce((a,b) => a + b);
}
from __builtin__ import int
def nestedLists(mylist):
sum = 0
if checkIfAllInt(mylist):
result = addList(mylist)
return result
else:
for value in mylist:
sum = sum + nestedLists(value)
return sum
def addList(listdata):
if(type(listdata) is int):
return listdata
else:
return sum(listdata)
def checkIfAllInt(listdata):
check = True
if(type(listdata) is int):
return check
else:
for value in listdata:
if(not type(value) is int):
check = False
return check
return check
print nestedLists([1,[2,3,[4,5,[6,7]]]])

Categories

Resources