JavaScript объект как счетчик не увеличивается - PullRequest
0 голосов
/ 28 октября 2018

Я пытаюсь использовать объекты в качестве счетчика в JavaScript, чтобы найти наиболее повторяющиеся буквы в слове, но почему-то функция не работает, как я намереваюсь.Например, когда я вызываю findMaxRepeatCountInWord('expected'), объект letterCount заканчивается значением { e: 1, x: 1, p: 1, c: 1, t: 1, d: 1 }.Что не так с моим кодом?Разве e не должно иметь значение 3?

Мой код:

function findMaxRepeatCountInWord(word){
  var letterCount = {};
  word.split('').map(function(v){
    if(letterCount[v] != true){ letterCount[v] = 1 } 
    else(letterCount[v] ++)
  });
  return Object.values(letterCount).sort((a,b) => b-a)[0]
}

findMaxRepeatCountInWord('expected')

Ответы [ 6 ]

0 голосов
/ 28 октября 2018

Ваш код правильный, кроме условия if: if(letterCount[v] != true).

Решение: Вы можете легко решить проблему, просто изменив условие на следующее: if(letterCount[v] == undefined)

Проблема: Условие работает, как вы предполагали, когда:

  • letterCount[v] равно undefined
  • letterCount[v]равно 1

Но когда letterCount[v] становится больше 1, условие снова выполняется, потому что 2 != true равно true.По этой причине ваш код будет сбрасывать значения на 1 каждый раз, когда встречается нечетное число раз.

Для иллюстрации, если мы запустим ваш код для слова с двумя e, мы получаем:

findMaxRepeatCountInWord('expectd')
> 2

, но если есть третье вхождение буквы, как в вашем примере, число будет сброшено до 1.

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

0 голосов
/ 28 октября 2018
function findMaxRepeatCountInWord(word){
  var letterCount = {};
  word.split('').map(function(v){
    if(letterCount[v]==undefined){ letterCount[v]= 1 ;
} 
    else{letterCount[v]=letterCount[v]+1}
  });
  return Object.values(letterCount).sort((a,b) => b-a)[0]
}

var x=findMaxRepeatCountInWord('expected');
console.log(x);
0 голосов
/ 28 октября 2018

Вот еще одна версия веселья сравнения JS:

 console.log(
   0 != true, // true
   1 != true, // false
   2 != true // true
   3 != true // true
);

Если вы сравните число и логическое значение, логическое значение будет преобразовано в число (0 -> false, 1 -> true), тогда будет выполнено сравнение на равенство, и поэтому только 1 равно true. Поэтому, если он достигнет 2, он снова войдет в первую ветвь и сбросит счетчик до 1.

0 голосов
/ 28 октября 2018

Это не сработает так, как вы надеетесь:

 if(letterCount[v] != true)

Попробуйте попробовать с !hasOwnProperty (и использовать вместо карты forEach вместо):

function findMaxRepeatCountInWord(word){
    var letterCount = {};
    word.split('').forEach(function(v){
      if(!letterCount.hasOwnProperty(v)){ letterCount[v] = 1 } 
      else letterCount[v] ++
    });
    console.log("letter counts", letterCount)
    return Object.values(letterCount).sort((a,b) => b-a)[0]
  }
  
  console.log(findMaxRepeatCountInWord('expected'))
  

Вы также можете сохранить стоимость сортировки с помощью:

return Math.max(...Object.values(letterCount))
0 голосов
/ 28 октября 2018

Необходимо проверить свойство следующим образом: if (v in letterCount) это самый надежный способ проверить, является ли ключ свойством объекта.

Этот подход возвращает построенный объект

function findMaxRepeatCountInWord(word) {
  var letterCount = {};
  word.split('').map(function(v) {
    letterCount[v] = (letterCount[v] || 0) + 1;
  });
  
  return letterCount;
}

console.log(findMaxRepeatCountInWord('expected'))
.as-console-wrapper { max-height: 100% !important; top: 0; }

Кроме того, использование функции Array.prototype.map не лучший способ решить эту проблему, поскольку вы создаете ненужный массив.

Альтернативный подход с использованием функции Array.prototype.reduce для группировки букв

function findMaxRepeatCountInWord(word) {
  return word.split('').reduce((a, c) => {
    a[c] = (a[c] || 0) + 1;
    return a;
  }, Object.create(null));
}

console.log(findMaxRepeatCountInWord('expected'))
.as-console-wrapper { max-height: 100% !important; top: 0; }
0 голосов
/ 28 октября 2018

Значение if должно быть:

if(!letterCount[v]){ letterCount[v] = 1 } 
else {letterCount[v]++}

Для минимального изменения кода.Другие ответы отполируют это больше.


Применимо к коду OP:

function findMaxRepeatCountInWord(word){
  var letterCount = {};
  word.split('').map(function(v){
    if(!letterCount[v]){ letterCount[v] = 1 } 
    else(letterCount[v] ++)
  });
  console.log(letterCount)
  return Object.values(letterCount).sort((a,b) => b-a)[0]
}

findMaxRepeatCountInWord('super expected');
...