I am trying to find the solution for the below ask –
Create a function that accepts a chemical compound (H2O) string and returns a JSON object containing key-value pairs where keys are the element symbols and the values are the element counts.
"H2O" => {"H": 2, "O": 1}
"C6H12" => {"C": 6, "H": 12}
"COOH" => {"C": 1, "O": 2, "H": 1}
I have written a solution –
function parseChemicalCompound(chemical) {
let result = {};
let currentElement = "";
let currentCount = ""; // Initialize as string to handle leading digits
for (let i = 0; i < chemical.length; i++) {
let char = chemical[i];
let nextChar = i < chemical.length - 1 ? chemical[i + 1] : ""; // Access next character safely
if (char >= "A" && char <= "Z") {
// Handle element completion
if (currentElement !== "") {
if (currentCount === "") currentCount = "1"; // Default to 1 if no count
result[currentElement] = parseInt(currentCount);
}
currentElement = char;
currentCount = ""; // Reset for the new element
} else if (char >= "a" && char <= "z") {
currentElement += char; // Handle multi-letter elements
} else if (!isNaN(parseInt(char))) {
currentCount += char; // Append digits for counts
} else if (char === nextChar) {
// Handle consecutive identical characters for counts
currentCount += char;
// i++; // Skip the next character since it's already processed
} else {
// Optionally handle invalid characters
console.warn(`Invalid character: ${char}`);
}
}
// Handle the last element
if (currentElement !== "") {
if (currentCount === "") currentCount = "1"; // Default to 1 if no count
result[currentElement] = parseInt(currentCount);
}
return result;
}
code sandbox – https://codesandbox.io/p/sandbox/basic-javascript-forked-mzpk49?file=%2Fsrc%2Findex.js%3A5%2C1
But this doesn’t work for the last test case
"COOH" =>
For this it always gives
{"C": 1, "O": 1, "H": 1}
But the result should have "O": 2
{"C": 1, "O": 2, "H": 1}
Suggest some good answers.
2
Answers
Instead of looping character by character, use a regular expression. Each element can be matched with the regexp
([A-Z][a-z]?)(d*)
. The first capture group is the element abbreviation (an uppercase letter optionally followed by a lower case letter), the second group is the optional atom count. Loop over all the matches to create the object.You were really close! You just need to add to the total (
result
) instead of assigning a new total.Summary of changes
So, instead of just assigning:
You should add the current count to keep a running total.
If the result doesn’t exist, treat it as zero. Note this change needs to be made in both (2) places.
Also, the branch that checks if the chars are the same is not necessary. You can remove the check and the block that follows it.
Full example: