11521 sujets

JavaScript, DOM et API Web HTML5

Bonsoir à tous,

J'ai écrit un code très simple qui permet de suggérer des titres d'oeuvre lorsque l'on entre des mots-clefs dans un champ texte. J'ai placé les noms d'auteurs dans un objet et attribué à chacun d'eux une array avec une liste d’œuvres. Une fonction vérifie que le mot-clef existe dans le "dictionnaire" et choisit un titre au hasard dans l'array qui lui est associée.

Le problème c'est qu'il faut entrer le nom complet de la valeur pour que ça marche (par ex : "Baudelaire Spleen et idéal") au lieu de pouvoir entrer simplement l'un ou plusieurs des mots-clefs qu'elle contient (juste "spleen" ou "Baudelaire spleen" par exemple).

J'ai réussi grâce à la méthode indexOf, mais seulement en l'utilisant avec des conditionnelles directement intégrées à la fonction, ce qui alourdit énormément le code (et rend presque impossible l'élaboration d'une grande base de données).

Je cherche donc à garder le dictionnaire séparé de la fonction comme dans le fiddle mais en arrivant cette fois à autoriser la correspondance même si seulement l'un ou plusieurs des mots-clefs est entré dans le champ texte (au lieu du libellé complet).

Du coup, quelle méthode serait adaptée dans mon cas ? Est-il possible d'utiliser la méthode indexOf dans avec un objet ?

Si quelqu'un a une idée, je lui serais très reconnaissante ;D
Merci!

http://jsfiddle.net/tttjrq9d/2/
Modifié par balleronde (17 Sep 2016 - 10:09)
Merci Zelena ! c'est presque ce que je cherche ! ça fait plaisir parce que je commençais à désespérer d'y arriver toute seule Smiley ravi

Le problème avec .startsWith() c'est qu'elle vérifie qu'une partie de la phrase est identique à une autre au lieu de regarder dans toute la phrase.

Je vais essayer de préciser mon problème, dites-moi s'il vous plaît si je ne suis pas claire Smiley smile

Ce que je veux faire :
Au lieu de comparer les phrases complètes, il faudrait que la fonction "décompose" la phrase écrite dans l'input pour comparer les mots. Si 4 mots dans la phrase correspondent à 4 mots d'une phrase stockée dans ma variable "dictionnaire", elle doit arriver à établir la correspondance.

Pour schématiser :
Si j'ai la phrase "être ou ne pas être, telle est la question" dans ma variable "dictionnaire"

1. j'écris juste les mots "être ne pas question" dans l'input puis appuie sur entrée.
2. la fonction observe chacun des mots : " être ", " ne ", " pas ", " question " et regarde si ces mots existent dans une phrase de la variable "dictionnaire"
3. La fonction établit que "être ne pas question" = " être ou ne pas être telle est la question " car 4 mots sont identiques


if (dictionary[request]) { // Condition à reformuler
   result = dictionary[request];
}

Jsfiddle simplifié : http://jsfiddle.net/tttjrq9d/2/

Bref c'est sûrement très simple mais je n'arrive pas à l'écrire en javascript...

PS : peut-être avec les méthodes split() et indexOf() ?

Merci encore pour votre aide
Modifié par balleronde (11 Sep 2016 - 05:21)
balleronde a écrit :
Merci Zelena ! c'est presque ce que je cherche ! ça fait plaisir parce que je commençais à désespérer d'y arriver toute seule Smiley ravi

Le problème avec .startsWith() c'est qu'elle vérifie qu'une partie de la phrase est identique à une autre au lieu de regarder dans toute la phrase.

Je vais essayer de préciser mon problème, dites-moi s'il vous plaît si je ne suis pas claire Smiley smile

Ce que je veux faire :
Au lieu de comparer les phrases complètes, il faudrait que la fonction "décompose" la phrase écrite dans l'input pour comparer les mots. Si 4 mots dans la phrase correspondent à 4 mots d'une phrase stockée dans ma variable "dictionnaire", elle doit arriver à établir la correspondance.

Pour schématiser :
Si j'ai la phrase "être ou ne pas être, telle est la question" dans ma variable "dictionnaire"

1. j'écris juste les mots "être ne pas question" dans l'input puis appuie sur entrée.
2. la fonction observe chacun des mots : " être ", " ne ", " pas ", " question " et regarde si ces mots existent dans une phrase de la variable "dictionnaire"
3. La fonction établit que "être ne pas question" = " être ou ne pas être telle est la question " car 4 mots sont identiques


if (dictionary[request]) { // Condition à reformuler
   result = dictionary[request];
}

Jsfiddle simplifié : http://jsfiddle.net/tttjrq9d/2/

Bref c'est sûrement très simple mais je n'arrive pas à l'écrire en javascript...

PS : peut-être avec les méthodes split() et indexOf() ?

Merci encore pour votre aide

Sur ces bases, l'algorithme "simpliste" (c'est à dire pas forcément le plus optimisé) pourrait être:
- extraction des mots de la phrase en utilisant la fonction Split, avec comme délimiteur le caractère espace, ce qui devrait retourner un tableau
- parcours du tableau pour rechercher / compter les mots "validants", c'est à dire ceux permettant de considérer la phrase comme correcte.
Répondant depuis un téléphone portable, je ne peux pas tester / fournir le code javascript correspondant...
Cet algorithme est assez primaire mais l'idée est là.
Pour être vraiment efficace, il faudrait ajouter une phase intermédiaire durant laquelle le tableau est parcouru pour supprimer, par exemple, les caractères de ponctuation pouvant être accolés à droite des mots issus du Split (ex. virgule, etc.).
De même, chaque mot du tableau pourrait être mis en minuscule afin de simplifier la dernière phase de recherche (comparaison avec les mots "signifiants").
Bonne continuation.
Merci specat, c'est exactement ce que je cherche !

J'ai déjà écrit une fonction qui supprime la ponctuation et remplace les accents et majuscules par des minuscules simples.

Là où je bloque c'est vraiment sur les deux points que tu as cité :

[description du problème obsolète]
Modifié par balleronde (12 Sep 2016 - 05:29)
Finalement je crois que je tiens le bon bout, merci pour tes précieux conseils specat ! Smiley smile

En revanche il me reste toujours ces deux problèmes que je ne parviens pas à résoudre :

1 - Le code établit bien une correspondance même si j'écris les mots dans le désordre, s'ils ne sont pas collés, ou si je ne les écris pas tous. En revanche ça ne marche pas aussi dans l'autre sens. Par exemple :
a écrit :
"pommes fades, mures : jaunes." = pommes mures poires

Ici ça ne marche pas car "poires" ne figure pas dans la phrase de gauche.
Comment puis-je autoriser la correspondance même si je tape un mot qui n'est pas dans la phrase ? Le critère devrait être le nombre de mots identiques, indépendamment des mots manquants ou en trop.

2 - Je cherche toujours un moyen d'utiliser l'objet "dictionary" (en début de code) au lieu des <li> en html. L'objectif est de retourner le nombre associé aux phrases du dictionnaire lorsqu'une corresponde est établie.

Voilà où j'en suis actuellement : https://jsfiddle.net/balleronde/239mfm0x/1/

Merci encore pour vos suggestions
Bonjour,
Des idées ou des articles à me conseiller pour résoudre mon problème ?

J'avoue avoir du mal avec la syntaxe JS dès qu'elle concerne des manipulations un peu plus "complexes" sur des objets ou des arrays. Les articles ou les vidéos que je trouve sur google répètent souvent les mêmes informations qui ne m'aident pas vraiment. Si vous avez une quelconque piste...
merci

PS : j'ai modifié le titre du sujet qui me semble plus précis
Bonjour,
La méthode levenstein du PHP (voir cette page) pourrait vous donner des idées pour trouver les titres les plus proches d'une chaîne donnée, d'autant plus qu'Il existe des versions javascript
Modifié par Julien de Prabere (24 Sep 2016 - 16:44)