search method

List<User> search(
  1. String query
)

It does an search on a list of User and returns users with id or name containing the query.

Results are returned sorted by their edit distance from the searched string, distance is calculated using the levenshtein algorithm.

Implementation

List<User> search(String query) {
  String normalize(String input) => input.toLowerCase().diacriticsInsensitive;

  final normalizedQuery = normalize(query);

  final matchingUsers = <User, int>{}; // User:lDistance

  for (final user in this) {
    final normalizedId = normalize(user.id);
    final normalizedUserName = normalize(user.name);
    final lDistance = normalizedUserName.levenshteinDistance(normalizedQuery);
    final containsId = normalizedId.contains(normalizedQuery);
    final containsName = normalizedUserName.contains(normalizedQuery);
    if (lDistance < 3 || containsId || containsName) {
      matchingUsers[user] = lDistance;
    }
  }

  final entries = matchingUsers.entries.toList(growable: false)
    ..sort((prev, curr) {
      bool containsQuery(User user) =>
          normalize(user.id).contains(normalizedQuery) ||
          normalize(user.name).contains(normalizedQuery);

      final containsInPrev = containsQuery(prev.key);
      final containsInCurr = containsQuery(curr.key);

      if (containsInPrev && !containsInCurr) {
        return -1;
      } else if (!containsInPrev && containsInCurr) {
        return 1;
      }
      return prev.value.compareTo(curr.value);
    });

  return entries.map((e) => e.key).toList(growable: false);
}