Reputation: 2741
I want to write a function to compress the characters of a string such as 'bbbab' would be converted to 'b3ab' and I'm getting stuck
it's only printing "b3"
here's the code so far
let string = 'bbbab';
let letters = string.split("");
let currentAlphabetLetter = letters[0];
let count = 0;
let newString = [];
string.split("").forEach(letter => {
if (letter === currentAlphabetLetter) {
count++;
} else {
if (count > 0) {
newString.push(`${currentAlphabetLetter}${count}`);
} else {
newString.push(`${letter}`);
}
count = 0;
currentAlphabetLetter = letter;
}
})
console.log(newString);
Upvotes: 1
Views: 148
Reputation: 26161
You may do as follows;
var str = 'bbbabccc',
res = [...str].reduce((r,c,i) => (r[r.length-1][0] === c || !i) ? (r[r.length-1] += c, r)
: r.concat(c), [""])
.reduce((r,s) => r + s[0] + (s.length-1 ? s.length : ""), "");
console.log(res);
We have two .reduce()
s cascaded here but first it's good to know that [...str]
turns into ["b", "b", "b", "a", "b", "c", "c", "c"]
.
The first .reduce()
will reduce it to an array of strings such as ["bbb", "a", "b", "ccc"]
.
The second .reduce()
will further reduce it to the result. The inner mechanics of each reducers are for you to solve.
However, as hint, keep in mind that the comma operator ,
as in (r[r.length-1] += c, r)
takes the last element of r
array (accumulator here) adds c
to the end of it and returns r
.
Upvotes: 1
Reputation: 72
Like this should work for you
let string = 'bbbab';
let newString = [];
if (string.length < 2) { console.log(string); }
else {
let letters = string.split("");
let prev = letters[0];
let count = 1;
for( var i = 1; i < letters.length; i++) {
if (letters[i] !== prev) {
count > 1 ? newString.push(`${prev}${count}`) : newString.push(`${prev}`);
count = 1;
} else {
count++;
}
prev = letters[i];
}
/* last element push */
count > 1 ? newString.push(`${prev}${count}`) : newString.push(`${prev}`);
console.log(newString.join(""));
}
Upvotes: 0
Reputation: 780984
When you start a new letter, you need to set count
to 1
, otherwise you're not counting the first occurrence of the character.
This isn't a problem at the very beginning of the string, because you process the first letter twice: you extract it with let currentAlphabetLetter = letters[0];
and then process it again on the first iteration of the forEach
. To make the beginning of the string the same as other occurrences, you should iterate over the substring starting with the 2nd character.
And rather than pushing onto an array, you should append to a string.
When count
is 1
you need to append currentAlphabetLetter
, not letter
.
let string = 'bbbab';
let letters = string.split("");
let currentAlphabetLetter = letters[0];
let count = 1;
let newString = "";
string.substr(1).split("").forEach(letter => {
if (letter === currentAlphabetLetter) {
count++;
} else {
if (count > 1) {
newString += `${currentAlphabetLetter}${count}`;
} else {
newString += `${currentAlphabetLetter}`;
}
count = 1;
currentAlphabetLetter = letter;
}
});
// Process the last letter
if (count > 1) {
newString += `${currentAlphabetLetter}${count}`;
} else {
newString += `${currentAlphabetLetter}`;
}
console.log(newString);
Upvotes: 1