0

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 Answers5

0

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

vincendep
  • 528
  • 4
  • 10
0

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');
  }
}
user3770373
  • 33
  • 1
  • 7
  • We don't know what we are looking for, that is why we are searching and checking null:) – Md. Yeasin Sheikh Feb 28 '23 at 15:06
  • Then you could use ``` String? result = lookup.entries.firstWhereOrNull((element) => IterableEquality().equals(element.key,key))?.value; ``` But you should think if your software design is done properly if you have to do it this was – user3770373 Feb 28 '23 at 15:17
0

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
krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
0

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?

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
0

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;
}
Alex Sunder Singh
  • 2,378
  • 1
  • 7
  • 17