2017-04-13 3 views
2

Angesichts einer sortierten Array von Strings und Benutzereingaben muss ich das relevanteste Ergebnis zurückgeben.JS - Erstellen Smart Auto abgeschlossen

Beispiel: Array = ['Apple','Banana and Melon','Orange'] und Benutzereingabe = 'Mellllon' der zurückgegebene Wert 'Banana and Melon'

für den richtigen Algorithmus zu implementieren, um eine effiziente automatische Komplettlösung und nicht aus der Box Ich bin auf der Suche sein sollte ein.

+0

Ich würde Ihnen empfehlen, einen Blick auf [Schneller JavaScript Fuzzy-String-Matching-Funktion?] (Https://codereview.stackexchange.com/a/23905/105433) – Redu

Antwort

1

Levenshtein Abstand scheint für dieses Problem richtig zu sein. Sie müssen Abstand zwischen jedem Wort in der Matrix berechnen, check it out,

function findClosestString(arr, inputvalue) { 
    let closestOne = ""; 
    let floorDistance = 0.1; 

    for (let i = 0; i < arr.length; i++) { 
    let dist = distance(arr[i], inputvalue); 
    if (dist > floorDistance) { 
     floorDistance = dist; 
     closestOne = arr[i]; 
    } 
    } 

    return closestOne; 
} 

function distance(val1, val2) { 
    let longer, shorter, longerlth, result; 

    if (val1.length > val2.length) { 
    longer = val1; 
    shorter = val2; 
    } else { 
    longer = val2; 
    shorter = val1; 
    } 

    longerlth = longer.length; 

    result = ((longerlth - editDistance(longer, shorter))/parseFloat(longerlth)); 

    return result; 
} 

function editDistance(val1, val2) { 
    val1 = val1.toLowerCase(); 
    val2 = val2.toLowerCase(); 

    let costs = []; 

    for(let i = 0; i <= val1.length; i++) { 
    let lastVal = i; 
    for(let j = 0; j <= val2.length; j++) { 
     if (i === 0) { 
     costs[j] = j; 
     } else if (j > 0) { 
     let newVal = costs[j - 1]; 
     if (val1.charAt(i - 1) !== val2.charAt(j - 1)) { 
      newVal = Math.min(Math.min(newVal, lastVal), costs[j]) + 1; 
     } 
     costs[j - 1] = lastVal; 
     lastVal = newVal; 
     } 
    } 
    if (i > 0) { costs[val2.length] = lastVal } 
    } 

    return costs[val2.length]; 
} 

findClosestString(['Apple','Banana and Melon','Orange'], 'Mellllon'); 
+1

Super, das ist, was ich suchte, hier ist eine nette Implementierung für die Methode getDistance: https://gist.github.com/andrei-m/982927 –

1

Eine mögliche Lösung ist:

1) jeden Wert in einigen einfachen Code umwandeln (mit der gleichen einfachen Regeln konvertieren, zB Groß char in Kleinbuchstaben, wenn ein Zeichen die gleichen wie die Vorschaubilder ist, wird es nicht erhalten geschrieben und so weiter ..) so haben Sie ['aple','banana and melon', 'orange']

2) dann konvertieren Sie die Benutzereingabe, Mellllon =>melon

3) können Sie jetzt einfach laufen

return match_array.filter((x) => { x.indexOf(match_input)!=-1) );

1

Nun, wie ausführlich erklärt in the topic cited in my comment eine Fuzzy-Suche regex bereitgestellt nützlich sein könnten Sie alle Buchstaben des gesuchten Zeichenkette (Groß- und Kleinschreibung „m“ haben "e", "l", "o", "n") sind in der Eingabezeichenfolge in der Reihenfolge ihres Auftretens vorhanden. Also nach den generierten /M[^e]*e[^l]*l[^o]*o[^n]*n/i regexp von "Melon", "Maellion", "Mellloon" oder "nMelrNnon" sollten alle true zurückgeben.

function fuzzyMatch(s,p){ 
 
    p = p.split("").reduce((a,b) => a+'[^'+b+']*'+b); 
 
    return RegExp(p,"i").test(s); 
 
} 
 

 
var arr = ['Apple','Banana and Melon','Orange'], 
 
    inp = "MaellL;loin", 
 
    res = arr.filter(s => s.split(" ").some(w => fuzzyMatch(inp,w))); 
 
console.log(res);

die fuzzyMatch Funktion mit einer Trie-Typ-Datenstruktur Kombinieren Sie in der Tat könnten durchaus sinnvoll elastisches Auto komplette Funktionalität erhalten.

Verwandte Themen