How to find and pair the alphabets after the numbers in a string in order to reduce one expression?
Lets assume we have a string like string = "20hc+2a+2hc+9op+330o+10op"
, and we want to find the pair which same alphabet after numbers. First we should do split.('+')
and then we get an array [....]
, then we need to pair each alphabets after the numbers, to get something like below:
(20hc + 2hc) (2a) (9op+10op) (330o)
Finally, we need to sum the numbers for the matching pairs:
20+2 = 22hc
2 = 2a
9+10 = 19op
330 = 330o
To get a final result of:
22hc+2a+19op+330o
So, how can I approach this, it does not matter if they aren't sorted as long as the alphabet after numbers are same, in this case, could we use regex to match
them ? or indexOf
?
I think for readability, just use an indexOf pair conversion, and build a hash. For example:
const getPair = str => {
const numbers = '0123456789'
for (var i = 0; i < str.length; i++) {
if(numbers.indexOf(str.charAt(i)) < 0){ break }
}
return [str.slice(i), i === 0 ? 1 : parseInt(str.slice(0, i))]
}
//const eq = '20hc+2a+2hc+9op+330o+10op'
const eq = 'a+2ab+3b+4c+5bc'
const hash = eq.split('+')
.map(getPair)
.reduce((r, [key, val]) => {
r[key] = r[key] ? r[key] + val : val
return r
}, {})
const result = Object.entries(hash).map(([key, val]) => `${val}${key}`).join('+')
console.log(result)
I will do this in two steps. The first step generates an object with the keys
(alphabet letters) and the totals
(sum of numbers) for each key
. For this, we use String::split() and Array::reduce() in that order. An example of the generated object will be like:
{"hc": 22, "op": 19, ...}
The second step just formats the previous generated object to the desired output string. For this one we use Object.entries(), Array::map() and finally Array::join().
const input = "a+20hc+2a+2hc+9op+330o+10op";
// First, get keys and sum their total.
let res = input.split("+")
.reduce((acc, curr) =>
{
let [match, val, key] = curr.match(/(\d*)(\w*)/);
val = +val || 1;
acc[key] = acc[key] ? acc[key] + val : val;
return acc;
}, {});
console.log(res);
// Now, format to the output string.
res = Object.entries(res).map(([x, y]) => y + x).join("+");
console.log(res);
However, you should note that the previous approach won't work if you have subtractions
, but some minor changes can do the work:
const input = "-4a+20hc+2a+2hc+9op+330o+10op-340o";
// First, get keys and sum their total.
let res = input.split(/\+|(?=-)/)
.reduce((acc, curr) =>
{
let [match, val, key] = curr.match(/(-*\d*)(\w*)/);
val = +val || 1;
acc[key] = acc[key] ? acc[key] + val : val;
return acc;
}, {});
console.log(res);
// Now, format to the output string.
res = Object.entries(res)
.map(([x, y]) => y + x)
.join("+")
.replace(/\+-/, "-");
console.log(res);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With