Comment trouver efficacement le nombre individuel exact de tableaux de chaînes dans des tableaux de phrases?

Exemple

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.

ce que je fais:

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; 
    }
} 

Utilisation de RegEx: j'utilise \ b pour la limite. Mais le problème est dynamiquement je ne peux pas assigner la valeur: donc "/\b+sentences[i]+"\b/gi" ne fonctionne pas

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));
    }
}

Mais j'ai l'impression que les solutions ci-dessus ne sont pas efficaces. Si nous pouvons le faire de manière plus efficace et optimisée?

1
DirtyMind 25 févr. 2020 à 12:32

3 réponses

Meilleure réponse

Vous pouvez diviser les chaînes et filtrer par nom et obtenir la longueur du tableau.

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);

Complexité temporelle linéaire:

  • créer un objet avec les noms souhaités comme clé et zéro comme valeur pour le comptage,
  • se sentences joindre à une seule piqûre,
  • diviser cette chaîne
  • itérer les pièces et vérifier si une pièce est une clé de comptage, puis incrémenter le comptage.
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
Nina Scholz 25 févr. 2020 à 10:10

Vous pouvez utiliser l'objet RegExp pour les expressions dynamiques, ainsi que les fonctions map et reduce pour le comptage.

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);

Approche de complexité linéaire

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
Ele 25 févr. 2020 à 15:56

Créez l'expression régulière en entourant chaque nom de \b, en vous joignant à |, puis en passant à new RegExp. Ensuite, vous pouvez parcourir chaque phrase et chaque correspondance pour ce modèle et placer chaque correspondance sur un objet qui compte le nombre de correspondances pour chaque nom:

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);
2
CertainPerformance 25 févr. 2020 à 09:41