Как подсчитать количество вхождений слова в строку / сохранить его в объекте? - PullRequest
0 голосов
/ 19 октября 2018

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

Вот что у меня есть:

function countWords(str) {
  var strArray = str.split(' ');
  var output = {};

  if(str.length === 0) {
    return output;
  } else {
    strArray.map(function(n) {
      output[n] = str.split(n).length - 1;
    });
  }
  return output;
}

Вот вывод на консоль, когда я добавляю ...

console.log(strArray);
console.log(output);

... к коду:

Объект {a: 4, ask: 1, связка: 3, получение: 1, попытка: 1} ["ask", "a", "Связка", "попробовать", "a", "связка", "получить"," a "," Связка "]

По некоторым причинам число вхождений 'a' слишком велико, но все остальные значения верны.

Кто-нибудь видитчто я делаю не так?

Ответы [ 3 ]

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

Вместо внутреннего разделения просто увеличьте счет на единицу:

 strArray.forEach(function(n) {
  output[n] = (output[n] || 0) + 1;
 });
0 голосов
/ 19 октября 2018

Чтобы не считать ни одного вхождения слова, данную строку можно разделить пробелом или использовать для чтения слова за словом, используя пробел в качестве разделителя.

Вот пример примера в java, в этом примереКласс java Scanner используется для чтения слово за словом из заданного входного потока, если слово совпадает, значения счетчиков будут увеличиваться.

import java.util.Scanner;

public class WordOccurrencesInGivenString {
    public static void main(String[] args) {
        String word = "try";
        try (Scanner s = new Scanner(System.in)) {
            int counter = 0;
            String str = null;
            do {
                str = s.next();
                if (str.equals(word)) {
                    ++counter;
                }
            } while (!str.equals("exit"));
            System.out.println("No of occurrences of a word [" + word + "] : " + counter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

в этом примере слово «выход» используется для остановки чтения данных из входного потока и для вывода номера вхождений слова.

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

Проблема в том, что когда вы делаете

str.split(n)

, если n короткий, особенно если это один символ, такой как a, то вероятные вхождения его внутри других слов в строке будет также разделен.Например, 'abc a abc'.split('a') приведет к массиву длиной 4, хотя в строке есть только один a.

Одним из возможных шагов к решению проблемы будет использование регулярного выражения и установка границ слов.вокруг слова:

output[n] = str.split(new RegExp(String.raw`\b${n}\b`)).length - 1

Но было бы более элегантно не использовать промежуточные массивы, а вместо этого использовать reduce:

const countWords = str => str.split(' ').reduce((a, word) => {
  a[word] = (a[word] || 0) + 1;
  return a;
}, {});

console.log(countWords('ask a bunch, try a bunch, get a bunch'));
...