Как найти точный индивидуальный счетчик массива строк в массиве предложений? - PullRequest
1 голос
/ 25 февраля 2020

Как найти точный индивидуальный счетчик массива строк в массиве предложений?

Пример

var names= ["jhon", "parker"];
var sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"];

Answer : jhon ->1 times (do not consider jhonny), parker-> 3 times.

что я делаю:

var lenObj ={};
for(let i=0; i< sentences.length; i++){
    for(let j=0; j<name.length; j++){
        // split the sentences element and compare with each word in names array. And update the count in lenObj; 
    }
} 

Использование RegEx: Я использую \ b для восстановления dry. Но проблема в том, что динамически, я не могу присвоить значение: поэтому "/\b+sentences[i]+"\b/gi" не работает

for(let i=0; i< sentences.length; i++){
    for(let j=0; j<name.length; j++){
        var count = (str.match("/\b+sentences[i]+"\b/gi") || []).length; // is not working
        // if I hardcode it then it is working (str.match(/\bjhon\b/gi));
    }
}

Но я чувствую, что вышеприведенные решения не эффективны. Если есть какой-нибудь способ, которым мы можем сделать это более эффективно и оптимизировано?

Ответы [ 3 ]

2 голосов
/ 25 февраля 2020

Вы можете разбить строки и отфильтровать по имени и получить длину массива.

var names = ["jhon", "parker"],
    sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"],
    parts = sentences.join(' ').split(/\s+/),
    result = names.map(name => parts
        .filter(s => s === name)
        .length
    );

console.log(result);

Сложность линейного времени:

  • создать объект с требуемыми именами в качестве ключа и нулем в качестве значения для подсчета,
  • get sentences, соединенный с одним ядром,
  • разбить эту строку
  • итерировать части и проверить, является ли часть ключом подсчета, а затем увеличить счетчик.

var names = ["jhon", "parker"],
    sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"],
    counts = names.reduce((o, n) => (o[n] = 0, o), {});

sentences.join(' ').split(/\s+/).forEach(s => {
    if (s in counts) counts[s]++;
});

console.log(counts);
2 голосов
/ 25 февраля 2020

Вы можете использовать объект RegExp для выражений c, а также функции map и reduce для подсчета.

let names= ["jhon", "parker"],
    sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"],
    result = names.map(n => sentences.reduce((a, s) => a + (s.match(new RegExp(`\\b${n}\\b`, "g")) || []).length, 0));

console.log(result);

Подход линейной сложности

let names= ["jhon", "parker"],
    sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"],
    words = sentences.join(" "),
    result = names.map(n => (words.match(new RegExp(`\\b${n}\\b`, "g")) || []).length);

console.log(result);
2 голосов
/ 25 февраля 2020

Создайте регулярное выражение, окружив каждое имя \b, присоединившись к |, затем передав new RegExp. Затем вы можете перебирать каждое предложение и каждое совпадение для этого шаблона и помещать каждое совпадение в объект, который считает количество совпадений для каждого имени:

var names= ["jhon", "parker"];
var sentences = ["hello jhon", "hello parker and parker", "jhonny jhonny yes parker"];
const pattern = new RegExp(names.map(name => `\\b${name}\\b`).join('|'), 'gi');

const counts = {};
for (const sentence of sentences) {
  for (const match of (sentence.match(pattern) || [])) {
    counts[match] = (counts[match] || 0) + 1;
  }
}
console.log(counts);
...