fuzzySearch static method

List<SearchableItem> fuzzySearch(
  1. List<SearchableItem> items,
  2. String query, {
  3. SearchConfig config = const SearchConfig(),
})

Search items with fuzzy matching for typos and misspellings

Implementation

static List<SearchableItem> fuzzySearch(
  List<SearchableItem> items,
  String query, {
  SearchConfig config = const SearchConfig(),
}) {
  if (query.isEmpty) return items;

  final searchQuery =
      config.caseSensitive ? query : query.toLowerCase().trim();
  final results = <SearchableItem>[];
  final exactMatches = <SearchableItem>[];
  final startsWithMatches = <SearchableItem>[];
  final containsMatches = <SearchableItem>[];
  final fuzzyMatches = <SearchableItem>[];

  for (final item in items) {
    bool found = false;

    for (final field in config.searchFields) {
      final fieldValue = _getFieldValue(item, field);
      if (fieldValue == null) continue;

      final searchValue =
          config.caseSensitive ? fieldValue : fieldValue.toLowerCase();

      // 1. Exact matches
      if (searchValue == searchQuery) {
        exactMatches.add(item);
        found = true;
        break;
      }

      // 2. Starts with query
      if (!found && searchValue.startsWith(searchQuery)) {
        startsWithMatches.add(item);
        found = true;
        break;
      }

      // 3. Contains query
      if (!found && searchValue.contains(searchQuery)) {
        containsMatches.add(item);
        found = true;
        break;
      }

      // 4. Fuzzy search for typos and misspellings (only for queries >= 3 characters)
      if (!found &&
          config.fuzzyEnabled &&
          searchQuery.length >= 3 &&
          _isFuzzyMatch(searchQuery, searchValue, config.maxFuzzyDistance)) {
        fuzzyMatches.add(item);
        found = true;
        break;
      }
    }
  }

  results.addAll(exactMatches);
  results.addAll(startsWithMatches);
  results.addAll(containsMatches);
  results.addAll(fuzzyMatches);

  return results;
}