Sum of a number's digits with JavaScript - javascript

I have:
var nums = [333, 444, 555];
I want to treat each digit in a number as a separate number and add them together. In this case sums should be:
9 = 3 + 3 + 3
12 = 4 + 4 + 4
15 = 5 + 5 + 5
How to achieve this using JavaScript?

you can use a simple modulo operation and dividing
var a = [111, 222, 333];
a.forEach(function(entry) {
var sum = 0;
while(entry > 0)
{
sum += entry%10;
entry = Math.floor(entry/10);
}
alert(sum)
});

Here’s a different approach that converts the numbers to strings and converts those into an array of characters, then the characters back into numbers, then uses reduce to add the digits together.
var nums = [333, 444, 555];
var digitSums = nums.map(function(a) {
return Array.prototype.slice.call(a.toString()).map(Number).reduce(function(b, c) {
return b + c;
});
});
digitSums; // [9, 12, 15]
If your array consists of bigger numbers (that would overflow or turn to Infinity), you can use strings in your array and optionally remove the .toString().

Now in our days, with the advantages of ES6, you can simply spread each value of your array inside map, and the with reduce make the operation:
var numbers = [333, 444, 555];
const addDigits = nums => nums.map(
num => [...num.toString()].reduce((acc, act) => acc + parseInt(act), 0)
);
console.log(addDigits(numbers));

var nums = [333, 444, 555];
nums.map(number => [...String(number)].reduce((acc, num) => +num+acc , 0));
//output [9, 12, 15]
Unary plus operator (+num) is converting string into integer.

If you want to generate an array consisting of the sum of each digit, you can combine the .map()/.reduce() methods. The .map() method will create a new array based on the returned value (which is generated on each iteration of the initial array).
On each iteration, convert the number to a string (num.toString()), and then use the .split() method to generate an array of numbers. In other words, 333 would return [3, 3, 3]. Then use the .reduce() method to add the current/previous numbers in order to calculate the sum of the values.
var input = [333, 444, 555];
var sumOfDigits = input.map(function(num) {
return num.toString().split('').reduce(function(prev, current) {
return parseInt(prev, 10) + parseInt(current, 10);
}, 0);
});
//Display results:
document.querySelector('pre').textContent =
'Input: ' + JSON.stringify(input, null, 4)
+ '\n\nOutput: ' + JSON.stringify(sumOfDigits, null, 4);
<pre></pre>

Related

Converting an array of digits into a number for large numbers ignores some digits

I am converting array digits into a number e.g. [1,2,4] = 124.
This code is working for smaller values but when I checked for big values like [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3], I was not able to add the last 543 to my sum.
var plusOne = function(digits) {
let tsum = 0;
let sum = 0;
for (let i = 0; i < digits.length; i++) {
let k =Math.pow(10, (digits.length - (i + 1)));
tsum = arr[i]* k;
console.log(tsum);
sum = sum + tsum;
console.log(sum);
}
console.log(sum);
sum= sum + 1;
let cnt=0;
while (sum!=0) {
digits.unshift(Math.floor(sum%10));
sum = Math.floor(sum/10);
cnt++;
}
digits.length = cnt;
return digits;
};
let arr = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3];
console.log(plusOne(arr));
First, join the digits and make a string:
const joined =[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3].join('')
// output: "6145390195186705543"
Second, convert the string to a BigInt:
const number = BigInt(joined)
Your method for adding a one to a an array of digits won’t work for large numbers. JavaScript stores all numbers as a floating point, so as Darshna Rehka and pesehr suggested, you should use BigInt for this. See Issue with combining large array of numbers into one single number
for more information.
Although this doesn’t directly answer your question, here’s a different implementation of plusOne that should work for larger numbers:
const plusOne = digits => {
// Base case: treat empty arrays as 0 so return [1]
// This part is important for the recursion below
if (!digits.length) return [1];
const init = digits.slice(0, -1);
const last = digits[digits.length - 1];
return last === 9
// 9 + 1 = 10, carry the 1 (add 1 to the rest of the digits)
// If there are no more digits to the left of the 9 (init.length === 0),
// plusOne(init) will just return [1] (base case)
? [...plusOne(init), 0]
// Simply add 1 to the last digit and keep the rest
: [...init, last + 1];
};
const arr = [6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3];
console.log(plusOne(arr).join(''));
console.log(plusOne([1, 8, 9]).join(''));
console.log(plusOne([9, 9, 9]).join(''));

Average value of Array

I need to calculate the average value of my datas, my datas are in an
array the problem is when i parseInt them into an integer i only get
one value back and when try as an example following thing:
console.log(array[0]/24)
i dont get nothing
this is my array:
info my array is coming from php to js (php connected to api)
var signal_GW1 = dataFromAjax.data.data1.map(function(innerData){
return innerData.map(function(row){
return row[1];
});
});
console.log(signal_GW1);
//OUTPUT on BROWSER CONSOLE
[Array(136)]
0: Array(136)
[0 … 99]
0: "-59"
1: "-59"
2: "-59"
3: "-59"
4: "-53"
5: "-63"
To get the average of your array you could do the following.
As the response from the server is returning strings you need to use parseInt to convert to a number.
const array = ['-59', '-57', '-59', '-57'];
const average = array.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue)) / array.length;
console.log(average);
const myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = 0
for (const value of myArray) { sum += value; }
const average = sum / myArray.length
console.log(`Average: ${average}`)
Basically: calculate the sum using Array.prototype.reduce, and divide the sum by the number of Array values (i.e. its length). About Array.prototype.reduce
const x = Array.apply(null, new Array(5))
.map(() => String(-Math.floor(100 * Math.random() + 1)));
// (+v) converts the string value to a Number
const meanX = x.reduce((a, v) => a + (+v), 0) / x.length;
console.log(`${JSON.stringify(x)} => Mean: ${meanX}`);
// or as a one liner
console.log(`Mean from one liner: ${
x.reduce( (a, v) => a + ((1/x.length) * +(v)), 0 ).toFixed(2)}`
);

Javascript filter not returning the expected int value

The JavaScript filter function not converting the item to integer by using the parseInt. Because of that string concatenation is going on rather than adding the values when used the filtered array in reduce function.
var numbers = ['1', 2, 3, 4,'hello'];
var intArray=numbers.filter(num => **parseInt(num)**);
var sum=intArray.reduce((tot, b) => tot+b,0);
The trick is to first filter out non int values and then convert all of them to int
filter with isNaN would eliminate hello and map with parseInt will convert strings o number to int
var numbers = ['1', 2, 3, 4, 'hello'];
var intArray = numbers
.filter(num => !isNaN(num)).map(x => parseInt(x))
Your filter is filtering out the items that cannot be coerced to a number, but the items are still not necessarily numbers - convert them to numbers before using + with them, perhaps with .map:
var numbers = ['1', 2, 3, 4, 'hello'];
var intArray = numbers
.filter(num => parseInt(num))
.map(Number);
var sum = intArray.reduce((tot, b) => tot + b, 0);
console.log(sum);
Or, you can do it all at once with reduce and isNaN:
var numbers = ['1', 2, 3, 4, 'hello'];
var sum = numbers.reduce((tot, b) => {
if (isNaN(b)) return tot;
return tot + Number(b);
}, 0);
console.log(sum);
You can also sum them in one reduce and skip the filter stage where "1" gets passed as valid value (which as pointed out already is the issue) etc.
var numbers = ['1', 2, 3, 4,'hello'];
const result = numbers.reduce((r,c) => (+r||0) + (+c||0))
console.log(result)

how to form the largest number from a set of an array in javaScript

I have an array with arr = [1,3,34,44,4,45,6,76,9,98,23] and want the largest number to be formed from the array above. O/P number is 99876645444343231.
I tried doing it in for these set of number and that is working fine for 2 digits but not for more then that. Can anyone suggest a generic answer?
You could take an array with stringed values and the concatinated values of a and b and the value of b and a and take the delta of it for sorting, which reflects the sort order of the two string for a greater value for later joining.
function getLargest(array) {
return array
.map(String)
.sort((a, b) => (b + a) - (a + b))
.join('');
}
console.log(getLargest([1, 3, 34, 44, 4, 45, 6, 76, 9, 98, 23]));
Comparison with a simple descending sorting by string, which returns the wrong result (second line).
function getLargest(array) {
return array
.map(String)
.sort((a, b) => (b + a) - (a + b))
.join('');
}
console.log(getLargest([1, 3, 34, 44, 4, 45, 6, 76, 9, 98, 23]));
console.log([1, 3, 34, 44, 4, 45, 6, 76, 9, 98, 23].sort().reverse().join(''));
Write a comparison function compare() and use it to sort numbers. Given two
numbers first and second, we compare two numbers firstsecond (second appended at the end of first) and secondfirst (first appended at the end of second). If firstsecond is larger, then first should come before second in output, else second should come before first.
function sortArray(arr){
arr.sort(function compare(first,second) {
var firstsecond ='' + first + second;
var secondfirst ='' + second + first;
return firstsecond>secondfirst ? -1:1;
})
}
function getLargestNumber(arr){
var largestNumber = arr.join('')
return largestNumber
}
var arr = [1,3,34,44,4,45,6,76,9,98,23]
sortArray(arr)
var result = getLargestNumber(arr)
alert(result)
How about:
const concatMax = (...nums) => nums.sort((a, b) => ('' + b + a) - ('' + a + b)).join('');
console.log(concatMax(1, 3, 34, 44, 4, 45, 6, 76, 9, 98, 23)); //99876645444343231
console.log(concatMax(2, 20, 24, 6, 8)); //8624220
Explanation:
The ... syntax allows an iterable such as an array expression or string to be spread in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
The concatenation of '' at the beginning of the sorting pass will implicitly cast the contextual a and b to string and would have the following mechanism each sorting pass:
n = 0
Let a = '1', b = '9'
What is (b + a) - (a + b) e.g. '91' - '19' ?
negative: sort a to an index lower than b, i.e. a comes first.
positive: sort b to an index lower than a, i.e. b comes first.
zero: leave a and b unchanged with respect to each other.
... N
References:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
Sort the array in descending order of first digit of each number(by converting to array of strings).
Join all numbers of sorted array.
function swapArrayElements(arr, indexA, indexB) {
let temp = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] = temp;
}
function largestNumber(arr) {
let arrOfStrings;
arrOfStrings = arr.map(n => n.toString());
for(let i = 0; i < arrOfStrings.length - 1; i++) {
for(let j = i + 1; j < arrOfStrings.length; j++) {
if(parseInt(arrOfStrings[i] + arrOfStrings[j]) < parseInt(arrOfStrings[j] + arrOfStrings[i])) {
swapArrayElements(arrOfStrings, i, j);
}
}
}
return arrOfStrings.join('');
}
let arr = [1,3,34,44,4,45,6,76,9,98,23];
const largestNum = largestNumber(arr);
console.log(largestNum);

Adding the sum of a multi dimensional number array in JavaScript

this may seem like a given but I want an answer where I only use what I believe to be functional programming... so no for() loops. Say I have a multi dimensional array which contains arrays of numbers and numbers only! Something like this:
var numberArray = [[1,5,12],[1,-1], [5,11,45,-3],[0,1,2] ... ];
Now instead of having nested loops I would like to use .forEach and / or .reduce to get the sum of all numbers in numberArray, however I would also like to perform an action so that any negative numbers are omitted or given the value 0 when doing the addition. I thought something like this would work:
numberArray.reduce(function(a, b) {
a.concat(b);
}, []);
but I am not sure how to perform the action to set negative numbers to 0 (or just omit them) and then get the sum...
Use Array#reduce() twice.
var numberArray = [[1, 5, 12], [1, -1], [5, 11, 45, -3], [0, 1, 2]],
sum = numberArray.reduce(function (r, a) {
return a.reduce(function (s, b) {
return b > 0 ? s + b : s;
}, r);
}, 0);
document.write(sum);
You may need to do reduce twice.
Try this
numberArray.reduce(function(prev,current){return prev.concat(current)}).reduce(function(prev,current){return prev+current});
DEMO
var numberArray = [[1,5,12],[1,-1], [5,11,45,-3],[0,1,2]];
var output = numberArray.reduce(function(prev,current){return prev.concat(current)}).reduce(function(prev,current){return prev+current});
document.body.innerHTML += output;
Try to use an nested reduce at this context,
var numberArray = [[1,5,12],[1,-1], [5,11,45,-3],[0,1,2]]
var x = numberArray.reduce(function(a, b) {
return a + b.reduce(function(c,d){
return c + ((d > 0) ? d : 0);
}, 0);
}, 0);
console.log(x); //206

Categories