Посчитать количество каждой цифры и создать объект

168
29 января 2022, 10:30

У меня есть функция, которая извлекает числа из аргументов и возвращает его в виде строки:

function countNumber(smth) { 
    return String(smth.match(/\d+/)); 
} 
 
console.log(countNumber('123098h76gfdd')); //=>12309876

countNumbers('erer384jj4444666888jfd123'); 
// => {'1': 1, '2': 1, '3': 2, '4': 5, '6': 3, '8': 4} 
countNumbers('jdjjka000466588kkkfs662555'); 
// => {'0': 3, '2': 1, '4': 1, '5': 4, '6': 4, '8': 2} 
countNumbers(''); // => {}

Теперь мне нужно посчитать количество каждой цифры и создать объект. например, в конце это должно выглядеть так, как показано выше:

Как это сделать правильно? Есть идеи? Помогите пожалуйста!

Answer 1

const countDigits = str => (str.match(/\d/g) || []).reduce( 
  (rslt, digit) => ((rslt[digit] = ~~rslt[digit] + 1), rslt) 
, {});  
 
const printObj = obj => console.log( 
  JSON.stringify(obj).replace(/[,:]/g, '$& ') 
);  
 
printObj(countDigits('erer384jj4444666888jfd123')); 
// => {'1': 1, '2': 1, '3': 2, '4': 5, '6': 3, '8': 4} 
printObj(countDigits('jdjjka000466588kkkfs662555')); 
// => {'0': 3, '2': 1, '4': 1, '5': 4, '6': 4, '8': 2} 
printObj(countDigits('')); // => {}

Вместо (str.match(/\d/g) || []) можно [...str.replace(/\D/g, '')] - результат будет одинаков, но у второго варианта возможен +1 проход по символам строки (зависит от внутренней реализации строк, и спред-оператора).

Answer 2

Или так.

var allowed = /\d+/;
var results = Array.prototype.reduce.call("123099998h76gfdd", function (data, letter) {
    if (allowed.test(letter)) {
        letter = letter.toLowerCase();
        if (data[letter] === undefined) {
            data[letter] = 0;
        }
        data[letter] += 1;
    }
    return data;
}, {});
var o = new Object();
for (var letter in results) {
    o[letter] = results[letter]
}
console.log(o);
Answer 3

Можно просто создать еще один объект, перевести строку в массив, и пробежаться по массиву:

var res = new Object();
"ssd243fs20324fs".split("").filter(char => char >= '0' && char <= '9')
  .forEach(d => res[d] = (res[d] || 0) + 1)

Сначала выпоняется фильтрация символов: проверка, что символ -- цифра. Далее для каждой цифры инкриментируется счётчик в res.

Результат: { 0: 1, 2: 3, 3: 2, 4: 2 }

Как я писал выше в комментарии, функция (автора вопроса) получения цифр не верная (нет цифр 76):

String('123098h76gfdd'.match(/\d+/)) == "123098"

PS: в старых браузерах или IE может не заработать. Но это поправить легко, и это касается и других ответов.

PPS: на мой взгяд, всякие reduce, используемые в других ответах, мало понятны новичку. Зато каждый, изучающий язык, знает про циклы, т.е. понять forEach должно быть не сложно.

READ ALSO
Проблемы с анимацией jQuery

Проблемы с анимацией jQuery

У меня есть код, который выполняется при вызове функции theBestFunction:

123
Всплывающая форма обратной связи при наведении на картинку

Всплывающая форма обратной связи при наведении на картинку

Как сделать так, чтобы при наведении на картинку открывалось модальное окно с формой обратной связи?

86
Конструктор слайдер карусель

Конструктор слайдер карусель

Всем приветЕсть конструктор слайдера-карусели, сейчас пытаюсь добавить точки и обозначение типа "01/04" в зависимости от текущего сайта

165
HTML дерево из массива (рекурсия)

HTML дерево из массива (рекурсия)

Помогите доработать хтмл дерево (рекурсия)Первый уровень сделал а следующий не получается

75