skip to Main Content

I am learning on how to use lookup in Flutter, this is an example that I came across.

void main() {
  Map<List<String>, String> lookup = {
    ['foo', 'bar']: 'foobar',
    ['baz', 'qux']: 'bazqux',
    ['hello', 'world']: 'helloworld',
  };

  List<String> key = ['foo', 'bar'];

  String? result = lookup[key];

  if (result != null) {
    print('Result: $result');
  } else {
    print('No match found for $key');
  }
}

But the problem is the result is ‘No match found for [‘foo’,’bar’], although the code is correct. It is supposed to return ‘foobar’ as the result, but I am not sure where the problem is and how to fix it.

5

Answers


  1. From the documentation…Lists are, by default, only equal to themselves. https://api.dart.dev/be/180791/dart-core/List/operator_equals.html

    Login or Signup to reply.
  2. Problem is how Dart compares Lists for equality. See here for more information on how to compare lists. But that wont work in the case here.

    If you use it lie this you will get the result because they key is the same object

    void main() {
        List<String> key = ['foo', 'bar'];
        Map<List<String>, String> lookup = {
          key: 'foobar',
          ['baz', 'qux']: 'bazqux',
          ['hello', 'world']: 'helloworld',
        };
    
    
        String? result = lookup[key];
    
      if (result != null) {
        print('Result: $result');
      } else {
        print('No match found for $key');
      }
    }
    
    Login or Signup to reply.
  3. The problem is you are trying to compare new List, List<String> key = ['foo', 'bar'] with the existing key of ['foo','bar'] which are not equal because of different references, so you need to make the reference of both the key point to the same variable key

    Example:

    void main() {
        List<String> key = ['foo', 'bar']; //👈 define the key on the top
    
        Map<List<String>, String> lookup = {
          key: 'foobar',                      // use the same key reference here
          ['baz', 'qux']: 'bazqux',
          ['hello', 'world']: 'helloworld',
        };
    
        String? result = lookup[key];
    
      if (result != null) {
        print('Result: $result');
      } else {
        print('No match found for $key');
      }
    }
    

    Output :

    Result: foobar
    
    Login or Signup to reply.
  4. You can use this function where I am using IterableEquality from

    import 'package:collection/collection.dart';
    
      String? getResult(Map<List<String>, String> map, List<String> key) {
        const eq = IterableEquality();
        try {
          final data = map.entries.singleWhere((element) => eq.equals(element.key,
              key)); // actually there are other function also available
    
          return data.value;
        } catch (e) {
          return null;
        }
      }
    

    And test

        String? result = getResult(lookup, key);
    

    You can check more about How can I compare Lists for equality in Dart?

    Login or Signup to reply.
  5. As declare key, which generate a new object, so it won’t be getting matched. To overcome with this, you can use custom comparison function to solve this.

    void main() {
      Map<List<String>, String> lookup = {
        ['foo', 'bar']: 'foobar',
        ['baz', 'qux']: 'bazqux',
        ['hello', 'world']: 'helloworld',
      };
    
      List<String> key = ['foo', 'bar'];
    
      String? result = lookup[lookup.keys.firstWhere((e)=> listEquals(e, key), orElse: () => key)];
    
      if (result != null) {
        print('Result: $result');
      } else {
        print('No match found for $key');
      }
    }
    
    bool listEquals<T>(List<T>? a, List<T>? b) {//This custom function which check two listed are having same content
      if (a == null) {
        return b == null;
      }
      if (b == null || a.length != b.length) {
        return false;
      }
      if (identical(a, b)) {
        return true;
      }
      for (int index = 0; index < a.length; index += 1) {
        if (a[index] != b[index]) {
          return false;
        }
      }
      return true;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search