JS - 创建智能自动完成

时间:2017-04-13 13:04:26

标签: javascript arrays algorithm search autocomplete

给定一个排序的字符串数组和用户输入,我需要返回最相关的结果。

示例:数组= ['Apple','Banana and Melon','Orange']且用户输入= 'Mellllon'返回值应为'Banana and Melon'

我正在寻找合适的算法来实现高效的自动完成解决方案,不是开箱即用的

3 个答案:

答案 0 :(得分:1)

一种可能的解决方案是:

1)将每个值转换为一些简单的代码(使用相同的简单规则,例如将大写字母转换为小写,如果char与预览相同,则不会被写入等等)所以你有['aple','banana and melon', 'orange']

2)然后转换用户输入Mellllon => melon

3)现在你可以简单地运行

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

答案 1 :(得分:1)

Levenshtein距离似乎适合这个问题。你需要计算数组中每个单词之间的距离,检查出来

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

答案 2 :(得分:1)

好吧,正如在the topic cited in my comment中精心解释的那样,只要您拥有搜索字符串的所有字母(不区分大小写的“m”,“e”,“l”,“o”,“o”),模糊搜索正则表达式就会派上用场。 n“)按出现顺序出现在输入字符串中。因此,根据“Melon”生成的/M[^e]*e[^l]*l[^o]*o[^n]*n/i正则表达式,“Maellion”,“MElllloon”或“nMelrNnon”都应返回true

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

fuzzyMatch函数与trie类型数据结构相结合,实际上可以获得非常合理的弹性自动完成功能。