Задача рассчитать и вернуть количество строк
Есть строка.
const stringCount = "ggggaaaazzzzzlllllluuuuuuuuu";
Задача написать функцию которая будет считать количество символов и вернуть такой результат g4a4z5l6u9
У меня получилось вот такой не рабочий код
const str = "ggggaaaazzzzzlllllluuuuuuuuu";
const strNumeric = (str) => {
let counter = 0,
currentItem = str[0],
arr = [];
[...str].forEach((iterator) => {
if (iterator !== currentItem) {
currentItem = iterator;
arr = [...arr, `${currentItem}${counter}`];
counter = 0;
} else {
counter += 1;
}
});
console.log(arr);
};
console.log(strNumeric(str));
Результат выполнения этого кода такой
[
"a4",
"z3",
"l4",
"u5"
]
Вторая попытка
const str = "ggggaaaazzzzzlllllluuuuuuuuu";
const strNumeric = (str) => {
let main = [],
count = 0,
arr = [];
[...str].forEach((a) => {
if (!arr.includes(a)) {
count = str.match(/a/g, "").length;
arr = [...arr, a];
main = [...main, `${a}${count}`];
} else {
count = 0;
}
});
console.log(main);
};
strNumeric(str);
Тут уже совсем близок к решению.
Поучаю такой массив -> ["g4", "a4", "z4", "l4", "u4"]
Проблема вот в этой строке -> count = str.match(/a/g, "").length;
Тут всегда получаю 4 почему-то. Почему пока неясно.
Хотелось бы увидеть более понятную реализацию, без однострочных функций и односимвольных переменных, пожалуйста.
Ответы (6 шт):
Моя идея такая: считать в цикле в ассоциативный массив, где ключ - символ, значение - количество символа в строке. Я извиняюсь, что упростил ваш код. Не разбираюсь в бабелях.
const str = "ggggaaaazzzzzlllllluuuuuuuuu";
function strNumeric(s) {
var tmp = [];
for (var i = 0; i < s.length; i++) {
var c = s[i];
tmp[c] = tmp[c] ? tmp[c] + 1 : 1;
}
var res = "";
for (var c in tmp) {
res += c + tmp[c];
}
return res;
}
console.log(strNumeric(str));
Я написал вам функцию, которая вернет объект, теперь с этими данными вы можете делать, что угодно.
const getBufferCountingСharacters = (characters) => {
buffer = {};
for (let i = 0; i < characters.length; i++) {
const character = characters[i];
if (characters.match(new RegExp(character, 'g')).length > 1) {
buffer[character] = characters.match(new RegExp(character, 'g')).length;
}
}
return buffer;
};
console.log(getBufferCountingСharacters('ggggaaaazzzzzlllllluuuuuuuuu'));
Однако вот вам решение требующее именно нужный результат.
const str = Object.entries(getBufferCountingСharacters('ggggaaaazzzzzlllllluuuuuuuuu')).flat().join('');
console.log(str);
Обратите внимания, что для работы нужна функция написанная выше.
Если буквы сгруппированы:
const str = "ggggaaaazzzzzlllllluuuuuuuuu";
function strNumeric(s) {
let r = '';
while(s) {
const a = s[0];
const newS = s.replace(new RegExp(a, 'g'), '');
r += a + (s.length - newS.length);
s = newS;
}
return r;
}
console.log(strNumeric(str));
Если существует несколько групп для одной и той же буквы:
const str = "ggggaaaazzzzzlllllluuuuuuuuugggggg";
function strNumeric(s) {
let r = '';
let count = 1;
for (let i = 1; i <= s.length; i++) {
if (s[i] != s[i - 1]) {
r += s[i - 1] + count;
count = 0;
}
count++;
}
return r;
}
console.log(strNumeric(str));
Попробуйте так:
let strNumeric = (str) => {
let map = {};
let result = "";
[...str].forEach((char) => {
!map[char] ? map[char] = 1 : map[char] = map[char] + 1;
})
for(let char in map){
result += char + map[char]
}
return result;
}
Решение:
const str = "ggggaaaazzzlllllluuuuuuuuu";
const strNumeric = (str) => {
let main = [],
count = 0,
arr = [];
[...str].forEach((item) => {
if (!arr.includes(item)) {
count = str.match(new RegExp(item, "g")).length;
arr = [...arr, item];
main = [...main, `${item}${count}`];
} else {
count = 0;
}
});
return main;
};
console.log(strNumeric(str).join(""));
Спасибо всем за ответы поставил всем плюсики.
Немного похож на ответ @Igor-я
const stringCount = "ggggaaaazzzzzlllllluuuuuuuuu";
const strNumeric = (str) => {
// Это строка будет содержать результат выполнения функции в виде строки
let countedStr = '';
// Переменная для отслеживания повторяющихся символов
let count = 0;
// Если у нас пустая строка выходим из выполнения функции
if ( str.length === 0 ){
return;
}
/*
* Обычный цикл for для перебора строки
* Отличие от привычного метода forEach который вы используете в том что
* тут не нужна разбивка через метод split либо спред оператора
*/
for(let i = 0; i < str.length; i++){
// Счетчик для каждого повторяющегося символа
count++;
if (str[i] !== str[i + 1]){
// Если символ не тот который был ранее добавляем его в countedStr
// вместе с count и сбрасываем count
countedStr += str[i] + count;
count = 0;
}
}
return countedStr;
}
console.log(strNumeric(stringCount));
Еще есть альтернативный алгоритм который делает обратное
Из этого "g4a4z5l6u9" делает это -> "ggggaaaazzzzzlllllluuuuuuuuu"
const countString = "g4a4z5l6u9";
const strNumeric = (str) => {
let splittedString = str.split("");
for(let i = 1; i < splittedString.length; i++) {
if (!isNaN(splittedString[i]) && !isNaN(splittedString[i - 1])) {
splittedString[i - 1] = splittedString[i - 1] + splittedString[i];
splittedString.splice(i, 1);
}
}
for (let i = 1; i < splittedString.length; i++ ){
if ( !isNaN(splittedString[i]) ){
splittedString[i - 1] = splittedString[i - 1].repeat(Number(splittedString[i]));
splittedString.splice(i, 1);
}
}
return splittedString.join("");
};
console.log(strNumeric(countString))
Комментарии ко второму коду добавлю потом.