You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter多词搜索实现:如何匹配包含部分输入关键词的食谱对象

现有实现的问题

你的当前版本代码存在几个可优化的点:

  • 无匹配结果时直接访问results[0]会触发数组越界异常
  • 没有做匹配优先级排序,可能优先返回匹配度更低的结果
  • 没有处理大小写差异,用户输入小写关键词就可能匹配失败
  • 关键词拆分后仅做任意匹配,可能出现结果和搜索意图偏差过大的情况

优化实现方案

我们可以统一大小写匹配规则,按匹配度给结果排序,优先返回匹配关键词更多、完全匹配的结果,同时增加兜底逻辑避免运行异常:

class SearchRecipe {
  // 无匹配结果时的兜底食谱实例,你可以根据业务需要调整兜底逻辑
  final RecipeModel defaultRecipe = RecipeModel();
  
  RecipeModel returnRecipe(String? suggestion) {
    // 空输入直接返回兜底
    if (suggestion == null || suggestion.trim().isEmpty) return defaultRecipe;
    
    final allRecipes = Store.instance.getAllRecipes();
    // 搜索关键词拆分后统一转小写,消除大小写差异
    final searchKeywords = suggestion.trim().toLowerCase().split(' ');
    
    // 给所有食谱计算匹配得分,得分越高匹配度越高
    final scoredRecipes = allRecipes.map((recipe) {
      final recipeName = recipe.recipeName?.toLowerCase() ?? '';
      // 统计匹配到的关键词数量
      int matchCount = searchKeywords.where((keyword) => recipeName.contains(keyword)).length;
      // 完全匹配的情况额外加权重,优先返回
      if (recipeName == suggestion.trim().toLowerCase()) {
        matchCount += 10;
      }
      return MapEntry(recipe, matchCount);
    }).toList();
    
    // 过滤完全不匹配的结果,按得分从高到低排序
    scoredRecipes.removeWhere((entry) => entry.value == 0);
    scoredRecipes.sort((a, b) => b.value.compareTo(a.value));
    
    // 有匹配结果返回得分最高的,无匹配返回兜底
    return scoredRecipes.isNotEmpty ? scoredRecipes.first.key : defaultRecipe;
  }
}

方案说明

  • 自动适配大小写输入,用户不管输入大写、小写、混合大小写都能正常匹配
  • 匹配优先级逻辑清晰:完全匹配的结果优先级最高,其次是匹配到更多关键词的结果,比如搜索Garlic butter时,同时匹配两个关键词的Garlic parmesan butter会排在仅匹配单个关键词的其他食谱前面
  • 覆盖了空输入、无匹配结果的边界场景,不会触发运行时崩溃
  • 如果你的食谱数量很大,也可以修改为遍历一次直接取最高匹配结果,不需要全量排序,性能更好

内容的提问来源于stack exchange,提问作者user14709104

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 03:45:03