Search code examples
flutterlistdartcollectionscontains

Flutter/Dart iterable.contains cannot find nested array?


I have an array of elements, for example a pair of integers, within which I am trying to find if a given pair is a match. For example,

    void main() {
    var someResolutions =  <List<int>>[
      [1920, 1080],
      [1920, 961],
      [961, 1920],
      [1366, 768],
      [1536, 864],
      [1280, 720],
      [1440, 900],
      [1600, 900]
    ];
    for ( List<int> resolution in someResolutions ) {
      bool matches = ( resolution == <int>[1920, 1080] );
      print( 'Does it match? $matches' );

    }
  
    print( someResolutions.contains( <int>[1920, 1080] ) );
    }

The output of the above in DartPad is:

Does it match? false
Does it match? false
Does it match? false
Does it match? false
Does it match? false
Does it match? false
Does it match? false
Does it match? false
false

It seems to me that both the first "does it match" and someResolutions.contains should be true in this situation.

The scenario is the same on DartPad and on this development Windows 11 machine:

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.4, on Microsoft Windows [Version 10.0.22621.674], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Build Tools 2019 16.11.16)
[√] Android Studio (version 2021.2)
[√] VS Code (version 1.72.2)
[√] Connected device (3 available)
[√] HTTP Host Availability

What am I missing?

Thanks!

I originally had the list set as a set of resolutions like <List<List> which produces the same result. There is no configuration of List.anything which will produce a match. I suppose I could go one level deeper and match into the nested array but this seems like a lot of work for something which should produce a match?

Edit: My question may now be, why is this typing as "JSArray" and how do I recast it...

void main() {
    var someResolutions =  <List<int>>[
      [1920, 1080],
      [1920, 961],
      [961, 1920],
      [1366, 768],
      [1536, 864],
      [1280, 720],
      [1440, 900],
      [1600, 900]
    ];
    for ( List<int> resolution in someResolutions ) {
      print( resolution );
      print( resolution.runtimeType );
      bool matches = ( resolution == <int>[1920, 1080] );
      print( 'Does it match? $matches' );

    }
  
    print( someResolutions.contains( <int>[1920, 1080] ) );
}

Resulting in:

[1920, 1080]
JSArray<int>
Does it match? false
[1920, 961]
JSArray<int>
Does it match? false
[961, 1920]
JSArray<int>
Does it match? false
[1366, 768]
JSArray<int>
Does it match? false
[1536, 864]
JSArray<int>
Does it match? false
[1280, 720]
JSArray<int>
Does it match? false
[1440, 900]
JSArray<int>
Does it match? false
[1600, 900]
JSArray<int>
Does it match? false
false

Solution

  • Try the following code:

    import 'package:collection/collection.dart';
    
    void main() {
      var someResolutions = <List<int>>[
        [1920, 1080],
        [1920, 961],
        [961, 1920],
        [1366, 768],
        [1536, 864],
        [1280, 720],
        [1440, 900],
        [1600, 900]
      ];
      for (List<int> resolution in someResolutions) {
        Function eq = const ListEquality().equals;
        bool matches = eq(resolution, <int>[1920, 1080]);
        print('Does it match? $matches');
      }
    
    }
    

    Result:

    Does it match? true
    Does it match? false
    Does it match? false
    Does it match? false
    Does it match? false
    Does it match? false
    Does it match? false
    Does it match? false