I have little problem with 'reduce' function.
let array = [
0: "720"
1: "1080"
]
array.reduce((a,b) => a + b)
There is problem, this return me 7201080, but i need 1800
You need convert string in number array.reduce((a,b) => +a + +b)
Provide initial value 0 for reduce callback function and convert string to number using Number()
let array = [
"720",
"1080"
]
console.log(array.reduce((a,b) => a + Number(b),0))
You say that your problem is (bold emphasis mine):
The numbers are joined instead of adding up
But that is not actually true, and it is not actually your problem.
The real problem is that there are no numbers in your code. There are only strings, and the binary infix + operator for strings is defined to perform string-concatenation: "A" + "b" === "Ab" // not 21.
The "best" way to fix your problem would be to fix it at the source, so that you have numbers instead of strings in the first place:
const array = [
720,
1080
];
console.log(array.reduce((a, b) => a + b));
// 1800
If that is not possible, e.g. because the code that generates this value is third-party code outside of your control, you should sanitize and adapt the data as soon as it enters your system, e.g. using Array.prototype.map and parseInt like this:
const thirdPartyArray = [
"720",
"1080"
];
const myArray = thirdPartyArray.map(str => parseInt(str, 10));
console.log(myArray.reduce((a, b) => a + b));
// 1800
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
Improve this question
I have a task to create a JS script that is able to find a string using binary search on an array containing all permutations of the alphabetic chars (only lower case) with length 6 - meaning all strings of this form:
['aaaaaa','aaaaab','aaaaac'.... 'zzzzzx','zzzzzy','zzzzzz']
(For a total of 26^6 items in the array)
Due to its size - I cannot generate the array locally and run a regular binary search on it, I need to be able to find the string in the n/2 position (n = 26^6) without creating the array.
On the other hand - I need to create some sort of 1-to-1 mapping between any string ('aaaaaa', 'zzzzzz') to a number and the other way around (from number to a string) which I can then make division calculations on and find the middle string and so on.
Preferably this should be in JS/TS as I want to make a node app out of it in the end.
Any ideas?
You can do something that works like binary numbers, I mean write the number in base26 and just use the exponant to find the corresponding letter at the corresponding spot.
let number = (26**6)/2
let exponants = number.toString(26)
let correspondingString = exponants
.split('')
.map(elem => parseInt(elem, 26))
.map(elem => (elem + 10).toString(36))
.join('')
console.log(correspondingString);
And reverse :
let string = 'naaaaa'
let correspondingNumber = string
.split('')
.map(elem => parseInt(elem, 36) - 10)
.map((elem, index) => elem*(26**(5-index)))
.reduce((sum, value)=> sum + value, 0)
console.log(correspondingNumber);
Note
This solution somewhat generalizes the question to larger numbers. The numbers relevant to the question can still be accomodated by the standard JS number type.
Solution
You can find the a-z representation for a given number by using JS's BigInt object (arbitrary size integers).
In case you are looking for the n/2-th number in a sorter permutation list, you'd go as follows:
let bn_x = ((26n ** 6n) / 2n) // BigInt notation
, s_x26 = bn_x.toString(26) // Convert in base 26. Digits are represented by 0-9,a-q
, s_atoz // Will hold s_x26 with digits represented by a-z
;
s_atoz =
Array
.from(s_x26) // string -> array of chars (ie. array of single-letter strings)
.map ( c => { // map a-q -> k-z, 0-9 -> a-j
return String.fromCharCode((( c.charCodeAt(0) < 'a'.charCodeAt(0) ) ? (c.charCodeAt(0) + ( 'a'.charCodeAt(0) - '0'.charCodeAt(0) )) : ( c.charCodeAt(0) + 10 )));
})
.join('') // array of chars -> string
;
console.log(s_atoz);
Of course, this specific result can also be deduced without computation.
The other way round works similar wrt the basic idea, but with a caveat: There is no radix-aware BigInt constructor at the time of writing, so the number needs to be assembled using the elementary steps from radix construction.
let s_atoz = 'naaaaa'
, abn_x26 =
Array
.from(s_atoz)
.map ( c => {
return BigInt(c.charCodeAt(0) - 'a'.charCodeAt(0));
})
, bn_x = abn_x26.reduce ( (previousValue, currentValue) => {
return BigInt(previousValue) * 26n + BigInt(currentValue);
}
, 0n
)
;
console.log(bn_x.toString());
If you just want to find the string that would occur at the given position in our imaginary array, we can calculate it with this numberToString function:
const n2s = (chars, len = chars .length) => (n) =>
(n < len ? '' : n2s (chars, len) (~~ (n / len)))
+ chars [n % len]
const fixedN2s = (digits, chars) => (n) =>
n2s (chars) (n) .padStart (digits, chars [0])
const numberToString = fixedN2s (6, 'abcdefghijklmnopqrstuvwxyz')
; [28, 268041553, 202214284, 26 ** 6 / 2] .forEach (
s => console .log (`numberToString (${s}) //=> "${numberToString (s)}"`)
)
We start with a helper function that does the bulk of the work, accepting first the alphabet we want to use. Here it's all the lower-case letters, but we could easily imagine doing the same against "abcde", for instance. It returns a function which takes a number, and then we peel off the last "digit: of that number, using it as an index into chars for the last character, and then for the rest of the string either returning an empty string (in our base case when n is less than our character count) or the value of a recursive call with that digit stripped and the remaining number shifted over by dividing our character count into the remainder.
We layer on a function, fixedN2s, which calls the above with an additional digits argument that tells the number of fixed positions to prefill with the first character. That is, n2s ('abc...z') (28) would yield 'bc', but we want to prefill with a, to get 'aaaabc'.
We use pass 6 and our alphabet to to this function to create numberToString, our main function.
Note that we could do the reverse simply enough as well, with somthing like this snippet:
const s2n = (chars,
encoding = [...chars] .reduce ((a, d, i) => ((a [d] = i), a), {})
) => ([...ss]) => ss .length == 0
? 0
: chars .length * s2n (chars, encoding) (ss .slice (0, -1)) + encoding [ss .at (-1)]
const stringToNumber = s2n ('abcdefghijklmnopqrstuvwxyz')
; ['abc', 'woolen', 'random', 'naaaaa'] .forEach (
s => console .log (`stringToNumber ("${s}") //=> ${stringToNumber (s)}`)
)
I have simple function of calculating the sum of numbers and strings in columns in a table. The sum works well and gives me results. The issue is that the sum has a lot of decimal places and I want to convert it to 2 decimal places, whenever I try
return sum.toFixed(2);
I end up with an error.
Type 'string' is not assignable to type 'number'.
Example of the sum from some columns
615.7142868041998, 0,10, 34.0476188659667, 14.761905193328857
What I have so far. The table columns contains both integers and strings, am using the reducer function to get only numbers
getSum(columnNumber) {
let sum = 0;
const columnNumberToPropertyMap = [
"id",
"teamNumber",
"rural",
"completed",
"entirehouseholdabsent",
"postponed",
"refused",
"vacant",
"dwelling"
];
const property = columnNumberToPropertyMap[columnNumber];
return this.rural.reduce((acc, curr) => {
//const adder = Number(curr[property]) || 0;
const adder = isNaN(Number(curr[property])) ? 0 : Number(curr[property]);
sum = acc + adder
return sum.toFixed(2);
}, 0);
}
How can I convert the sum to 2 decimal places. I have tried to pipe the result in the html | number : '1.2-2' it is not working also . thank you in advance
If you want to do the .toFixed after all the numbers have been summed, stick it after the reduce:
return this.rural.reduce((acc, curr) => {
//const adder = Number(curr[property]) || 0;
const adder = isNaN(Number(curr[property])) ? 0 : Number(curr[property]);
sum = acc + adder
return sum;
}, 0).toFixed(2);
.toFixed() converts the number into a string, that's why you are getting the error. You can convert it back to number like
parseFloat(sum.toFixed(2))
You can also create a utility function like
const formatDecimalNumber = (
num: number,
decimalPlacesToKeep = 2,
): number => parseFloat(num.toFixed(decimalPlacesToKeep))
Update
As pointed out in the comment, this is not a perfect solution. It all comes from the complexities of floating point math (not only limited to JavaScript). There's very good discussion in this thread.
On the other hand, .toFixed() is more like an utility function that rounds off and/or adjusts a number for easy representation. See docs here.
Some alternatives to this is approach is discussed here.
I was attempting a coding practice where I had to take a two digit integer, split the integer into its two digits and add those digits.
function addTwoDigits(n) {
var n = n
var string = n.toString()
var split = string.split("")
var integer= split.map(Number)
var z = integer[0]+integer[1]
console.log(z)
}
The output of my code was correct on each of the tests, but the code checks still failed. If anyone can provide some insight into why, I would appreciate it.
You could write the function this way
function addTwoDigits(n) {
return Math.floor(n/10) + (n%10));
}
I have encountered a similar issue before. The solution for me was returning the value, rather than logging it to the console.
Instead of console.log(z) try return z
Not sure what you mean by "but the code checks still failed". Here's a oneliner for n-digit numbers, using a reducer:
const sumOfIndividualDigits = n =>
[...`${n}`]
// ^ convert to Array of strings
.map(Number)
// ^convert element (back) to Numbers
.reduce( (acc, value) => acc + value, 0);
// ^ reduce to 1 value (sum)
console.log(sumOfIndividualDigits(22));
console.log(sumOfIndividualDigits(12345678));
I need to sort a list by the second batch number with JavaScript.
This is how it looks like now:
1101.19
1201.17
1301.09
What I need is:
1301.09
1201.17
1101.19
As I am still learning to program I can't figure out the issue. But need it at work.
Can someone help me understand the process of how to do it?
Sort the array depending on the decimal part. Here is the solution
Sort the array by selecting the decimal part of the number inside the sort function.
You can get the decimal part of any number by taking modulus operation with 0.1. Link.
const arr = [1101.19, 1201.17, 1301.09, 1201.20];
arr.sort((a, b) => {return (a % 1 - b % 1)});
console.log(arr);
You need to split each element before sort and compare second parts
let array = ["1101.69", "1701.57", "1301.09"];
array.sort((a,b)=>{
let pair1 = a.split('.');
let pair2 = b.split('.');
return ( parseInt(pair1[1]) < parseInt(pair2[1])) ? -1 : 1;
});
console.log(array);
I'm trying to sort a bunch of alphanumeric characters that look like this:
[AD850X, MP342X, OP452X, ZC234X, ZC540X]
The sorting should be based off only numbers, so I have to remove all alpha characters from this code and then I want to add those characters back after I sort them for the purposes of my code as they were before. For example, the above string should first look like this:
[850, 342, 452, 234, 540]
Then this,
[234, 342, 452, 540, 850]
And then finally this,
[ZC234X, MP342X, OP452X, ZC540X, AD850X]
I've been thinking about how to do this and I'm not sure how I would get the same two letters in the front to reattach to the numeric code after sorting (the last character, in this case "X,"would always be the same and I would concatenate this value after adding the first two alpha characters as they were before.
If anyone could help me out with this I would greatly appreciate it.
Thanks!
EDIT: One other question, once this runs, I want to only output the low and high value of the array (which can have different number of elements). I tried using .min and .max but not sure how to do that with the array that logs after you sort. So in the case above I would just need "ZC234X" and "AD850X".
You can use object as hash table to store element and its number and then sort by values form that object.
var data = ['AD850X', 'MP342X', 'OP452X', 'ZC234X', 'ZC540X'];
var obj = {}
data.forEach(e => obj[e] = e.match(/\d+/)[0])
var result = data.sort((a, b) => obj[a] - obj[b]);
console.log(result)
Instead of complicating it by removing the two first letters and then sorting, you could just sort the array comparing only the matched numbers inside each element.
var arr = ['AD850X', 'MP342X', 'OP452X', 'ZC234X', 'ZC540X'],
res = arr.sort((a,b) => a.match(/\d+/)[0] - b.match(/\d+/)[0]),
min = res[0],
max = res[res.length-1];
console.log("min value: " + min + " | max value: " + max);
You could use just the matched nummerical values for sorting. Array#sort works in situ.
This proposal uses a default value, if the regular expression does not match a number.
var array = ['AD850X', 'MP342X', 'OP452X', 'ZC234X', 'ZC540X'];
array.sort((a, b) => (a.match(/\d+/) || 0) - (b.match(/\d+/) || 0));
console.log('min value', array[0]);
console.log('max value', array[array.length - 1]);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }