Javascript - Find similar words in an Array ()

4

I have the following Array ()

palabras = ["anatomia","ana","angie","anatómico","anatómica","análisis","analogía","analizar","anabólico"];

Now, in HTML I have:

<!-- Qué complicado, oh mi Dios -->
<input type="text" name="palabra" class="p">

To capture the input value I have:

$(".p").on('input', function(event) {
    if ($.inArray($(this).val(), palabras);) {
        console.log("Reached!!");
    }else{
        console.log("Waiting / You're typing...");
    }
});

I would like to be able to capture the word without having to write it completely.

And then what I have only captures if the word is complete in the input: (

    
asked by Máxima Alekz 06.12.2016 в 16:02
source

3 answers

2

One way to solve this problem is to " clean " ( normalizar ) the words, that is, remove the characters with accents.

Steps to be taken:

  • Normalize the word arrangement.
  • Sort the standardized arrangement alphabetically.
  • Detect the entry of a value and normalize it.
  • Find the value entered in the array of standard words.
  • Here is a possible solution.

    $(function(){
      function normalizeWord(word) {
        var letters = [{
            search: 'áäàãâ',
            replace: 'a'
          }, {
            search: 'éëèê',
            replace: 'e'
          }, {
            search: 'íïìî',
            replace: 'i'
          }, {
           search: 'óöòõô',
           replace: 'o'
          }, {
            search: 'úüùû',
            replace: 'u'
          }, {
            search: 'ñ',
            replace: 'n'
          }, {
            search: 'ç',
            replace: 'c'
          }],
          normal;
        
        // Convertimos la palabra a minusculas
        word = word.toLowerCase();
        normal = word;
    
        // Por cada "letra"
        $.each(letters, function(idx, letter) {
          var re = new RegExp('[' + letter.search + ']', 'g');
          // Reemplazamos el caracter acentuado
          normal = normal.replace(re, letter.replace);
        });
      
        // Devolvemos un objeto con la palabra original y la normalizada
        return {
          original: word,
          normal: normal
        };
      }
      
      function normalizeWords(words) {
        var response = [];
      
        // Por cada palabra
        $.each(words, function(idx, word) {
          // Obtenemos la palabra normlalizada
          response.push(normalizeWord(word));
        });
      
        return response;
      }
      
      function sortNormalizedWords(a, b) {
        if (a.normal > b.normal) {
          return 1;
        }
        if (a.normal < b.normal) {
          return -1;
        }
        return 0;
      }
      
      function sortShortWords(a, b) {
        if (a.length > b.length) {
          return 1;
        }
        if (a.length < b.length) {
          return -1;
        }
        return 0;
      }
      
      //
    
       var palabras = ["anatomia","Ana","angie","anatómico","anatómica","análisis","analogía","analizar","anabólico","Analuz", "tu", "tú", "túnel"],
           // Obtenemos la palabras normalizadas (sin caracteres acentuados)
           words = normalizeWords(palabras);
      
      // Ordenamos el arreglo de la A a la Z
      words.sort(sortNormalizedWords);
      
      $( "#entrada").on('input', function() {
        var key = this.value,
            posibles = [],
            lucky = false;
        
        // Normalizamos el valor ingresado
        key = normalizeWord(key);
        
        // Por cada palabra
        $.each(words, function(idx, word) {
          // Validamos que contenga el valor ingresado
          if (word.normal.indexOf(key.normal) !== -1) {
            posibles.push(word.original);
            
            // Si es exactamente la palabra buscada
            if (key.original === word.original) {
              lucky = word.original;
            }
            // Si es igual a la palabras normalizada
            else if (!lucky && key.normal === word.normal) {
              lucky = word.normal;
            }
          }
        });
        
        // Imprimimos todas las palabras que contienen el valor ingresado
        $('#posibles').val(posibles.join(','));
        
        // Si no encontramos la pablabra exacta, 
        // ordenamos el arreglo de posibles
        // y devolvemos la primera
        if (!lucky) {
          lucky = posibles.sort(sortShortWords)[0];
         }
        $('#acertada').val(lucky);
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    Entrada:
    <input type="text" id="entrada"><br>
    Posibles:
    <input type="text" id="posibles" readonly><br>
    Mas acertada:
    <input type="text" id="acertada" readonly><br>
        
    answered by 06.12.2016 / 22:40
    source
    3

    palabras = ["anatomia","ana","angie","anatómico","anatómica","análisis","analogía","analizar","anabólico"];
    
    //Autocomplete funciona para completar palabras
    $( ".p" ).autocomplete({ 
        source: palabras,
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <script src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>
      <link rel="stylesheet" href="https://code.jquery.com/ui/1.11.2/themes/black-tie/jquery-ui.css" />
    
    <!-- tu input -->
    <input type="text" name="palabra" class="p">

    All documentation in Autocomplete

        
    answered by 06.12.2016 в 16:30
    1

    This question has interested me enough for that reason I have designed a simple auto-completion and I hope that my answer is useful for your problem, Let's see the code:

    $(document).ready(function () {
    
      var $input = $('.in');
      var $proof = $('.proof');
    
      // Tu arreglo de palabras
      var arr = [
        'ana',
        'angie',
        'anatomica',
        'analogo',
        'analizar',
        'analisis',
        'analogia',
        'anatomia',
      ];
    
      $input.on('input', handler);
    
      // Callback
      function handler (e) {
    
        $proof.empty();
        var data = $(this).val();
    
        /* Primero que todo ... */
        if (data !== '') {
    
          /**
           * La palabra justamente debe ser igual a alguna del arreglo.
           * Si no se debera encontrar alguna coincidencia con la palabra
           * ingresada.
           */
          if (arr.indexOf(data) !== -1) {
            $proof.append('la palabra es: ' + arr[arr.indexOf(data)]);
          } else {
    
            /**
             * Arreglo 'arrDiffLength' almacenara la diferencia
             * entre la/s palabra/s del arreglo 'arr' con la palabra
             * ingresada por ejemplo:
             *    'analisis'.length - 'ana'.length === 5
             */
            var arrDiffLength = [];
    
            /**
             * Arreglo 'arrShortWord' almacenara la/s palabra/s ajustadas
             * al tamaño de la palabra ingresada, es decir, 'analogo' ajustada
             * al tamaño de 'anali' seria 'analo' de esta forma se logra encontrar
             * si la palabra coincide parcialmente con una palabra del arreglo.
             */
            var arrShortWord = [];
    
            // Variable a utilizar para concatenar las palabras ajustadas.
            var temp = '';
    
            // Iteracion para encontrar la/s diferencia/s.
            for (var i = 0; i < arr.length; i++) {
              arrDiffLength.push(arr[i].length - data.length);
            }
    
            // Iteracion para encontrar las palabras ajustadas.
            for (var i = 0; i < arr.length; i++) {
              for (var j = 0; j < data.length; j++) {
                temp += arr[i][j];
              }
              arrShortWord.push(temp);
              temp = '';
            }
    
            /**
             * Valor minimo del arreglo 'arrDiffLength'.
             * Se utilizara para encontrar la palabra mas corta
             * que coincida con la palabra ingresada.
             */
            var minVal = Math.min.apply(null, arrDiffLength);
    
            // Indice del valor minimo en el arreglo 'arrShortWord'
            var indexOfMinVal = arrDiffLength.indexOf(minVal);
    
            /**
             * Condicional para verificar que almenos una o mas
             * coincidencias existen entre el arreglo 'arrShortWord'
             * y la palabra ingresada.
             */
            if (arrShortWord.indexOf(data) !== -1) {
              /**
               * Se busca la palabra que coincida con la palabra ingresada
               * y que sea la mas pequeña.
               * Si no, se itera para encontrar otras coincidencias.
               */
              if (arrShortWord[indexOfMinVal] === data) {
                $proof.append('La palabra es: ', arr[indexOfMinVal]);
              } else {
                for (var i = 0; i < arr.length; i++) {
                  if (arrShortWord[i] === data) {
                    $proof.append('La palabra es: ', arr[i]);
                    break;
                  }
                }
              }
            } else {
              $proof.append('La palabra no se encuentra.');
            }
          }
        }
    
        e.preventDefault();
      }
    });
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Auto comletador</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      </head>
      <body>
        <!-- Simple input -->
        <input class="in" type="text">
    
        <!-- Aqui se mostrara la palabra acertada -->
        <div class="proof"></div>
      </body>
    </html>

    I have designed it according to your criteria in the question and I have commented on the code so you can understand it quickly, I hope it will be helpful Greetings!.

        
    answered by 07.12.2016 в 00:51