Подсчет всех символов в строке

1

Я хочу подсчитать все символы в строке и вернуть ее объекту. Я попытался, но я не смог получить правильный ответ.

Это мой код:

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  a.forEach(function(s){
    var count=0;
    for(var j=0;j<a.length;j++){
      if(s==a[j]){
        count+=1;
      }
      obj[a[j]]=count;
    }
  });
  return obj;
}
console.log(countAllCharacters('banana'));

Выход:

{ b: 0, a: 3, n: 2 } 

Очевидно, что это неправильно.

Может ли кто-нибудь помочь мне в этом? Где я ошибаюсь?

Теги:
object
arrays

7 ответов

5

Минимальное необходимое изменение состоит в том, что obj[a[j]]=count; должно быть obj[s]=count; , потому что у вас есть эта строка, работающая на каждой итерации внутреннего цикла независимо от того, относится ли j к букве, которую вы сейчас подсвечиваете.

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  a.forEach(function(s){
    var count=0;
    for(var j=0;j<a.length;j++){
      if(s==a[j]){
        count+=1;
      }
      obj[s]=count;
    }
  });
  return obj;
}
console.log(countAllCharacters('banana'));

Однако вам не нужен вложенный цикл. Ваш внешний .forEach() может сразу обновить счетчик для текущей буквы:

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  a.forEach(function(s){
    obj[s] = (obj[s] || 0) + 1;
  });
  return obj;
}
console.log(countAllCharacters('banana'));

Это может быть сокращено с помощью .reduce():

function countAllCharacters(str) {
  return str.split("").reduce(function(obj, s){
    obj[s] = (obj[s] || 0) + 1;
    return obj;
  }, {});
}
console.log(countAllCharacters('banana'));

Обратите внимание, что (obj[s] || 0) означает использовать obj[s] значение, если оно правдиво, иначе используйте 0. Таким образом, первый раз, когда вы столкнулись с определенной буквы obj[s] будет undefined, что falsey, так, то 0 будет использоваться. В следующий раз, когда вы столкнетесь с этой буквой obj[s] будет 1, что является правдой.

4

Я бы использовал операцию уменьшения, например

const str = "banana"
const charCounts = Array.from(str).reduce((counts, char) => {
  counts[char] = (counts[char] || 0) + 1
  return counts
}, Object.create(null))

console.info(charCounts)
3

На самом деле вы можете рассчитывать на лучшую производительность, вы зацикливаете больше, чем вам нужно!

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  for(var j=0;j<a.length;j++){
    if(typeof obj[a[j]] !== 'undefined'){
      obj[a[j]]+=1;
    } else {
      obj[a[j]]=1;
     }
  }
  return obj;
}
console.log(countAllCharacters('banana'));
1

Проблема здесь в том, что вы назначаете obj[a[j]] = count; когда подсчет еще не завершен. Вам следует изменить следующие function(s):

  function(s){
    var count=0;
    for(var j=0;j<a.length;j++){
      if(s==a[j]){
        count+=1;
      }
    }
    obj[s]=count;
  }

Другой комментарий: код очень неэффективен, что является O(n^2). Вы можете упростить его гораздо дальше, чтобы получить алгоритм O(n):

  function(s){
    if (obj[s] == undefined) {
       obj[s] = 1;
    } else {
       obj[s] = obj[s] + 1;
    } 
  }
1

Я думаю, вам не нужно использовать forEach и цикл for когда вы можете сделать это только для foreach. Вот код.

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  a.forEach(function(s) {
    if (obj[s]) {
      obj[s] = obj[s] + 1;
    } else {
      obj[s] = 1;
    }
  });
  return obj;
}

console.log(countAllCharacters('banana'));

Надеюсь, поможет :)

  • 0
    Ну, это было очень полезно. Большое спасибо.
0

вы должны принести obj[a[j]]=count внутри вашего оператора if.

это должно возвращать правильные результаты

function countAllCharacters(str) {
  var a = str.split("")
  var obj = {}
  a.forEach(function(s){
    var count=0
    for(var j=0;j<a.length;j++){
      if(s===a[j]){
        count+=1
        obj[a[j]]=count
      }
    }
  })
  return obj
}
console.log(countAllCharacters('banana'))

приращение в obj также должно удовлетворять утверждению if.

0

Я понимаю, что это не самый красивый, но я надеюсь, что он показывает, как вы можете использовать консоль, чтобы помочь отлаживать циклы.

function countAllCharacters(str) {
  var a = str.split("");
  var obj = {};
  a.forEach(function(s){
  console.log(s);
    var count=0;
    for(var j in a){

      // commas can come in really handy and help avoid huge debug blocks.
      console.log('_',j,s,a[j]); 

      if(s==a[j]){
        console.log('count++');
        count++;
      }
      obj[s] = count;
    }
  });
  return obj;
}

console.log(countAllCharacters('banana'));

Ещё вопросы

Сообщество Overcoder
Наверх
Меню