flutterdartpls

.contains doesnt work like i thought it would Flutter/Dart


I am very new to Flutter and I run into a Problem. I want to check if the List: items, contains the word Hey and I know it does. So I wrote: if(items.contains('Hey')) to check. But it seems to skip the if part and only returns the else part. I wrote this easy Code to show you what I mean. I would really appreciate a quick answer, because of I really need to solve this problem.

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: Contain()));

class Liste {
  String Wort1;
  String Wort2;

  Liste({this.Wort1, this.Wort2});
}

class Contain extends StatefulWidget {
  @override
  _ContainState createState() => _ContainState();
}

class _ContainState extends State<Contain> {
  List<Liste> items = List<Liste>();

  @override
  void initState() {
    items = [
      Liste(Wort1: 'Hey', Wort2: 'Ho'),
      Liste(Wort1: 'HA', Wort2: 'HE'),
    ];
    super.initState();
  }

  function() {
    if (items.contains('Hey')) {
      return Center(
        child: Text('Works'),
      );
    } else {
      return Center(
        child: Text('Not Working'),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Title'),
      ),
      body: function(),
    );
  }
}

Solution

  • If you read the documentation you will see the following:

    Returns true if the collection contains an element equal to element.

    ...

    The equality used to determine whether element is equal to an element of the iterable defaults to the Object.== of the element.

    https://api.dart.dev/stable/2.8.4/dart-core/Iterable/contains.html

    So when you try do to if (items.contains('Hey')) it returns false since no object in your list are equal to 'Hey'. Actually, 'Hey' is a String and your list contains Liste objects.

    A better way to do what your are trying to do is to use .any like this which will iterate over your list and run a check for each element to check if any element returns true:

        if (items.any((e) => e.Wort1 == 'Hey' || e.Wort2 == 'Hey')) {
          return Center(
            child: Text('Works'),
          );
        }
    

    Alternative you can implement the == operator on Liste to actually return true if comparing to a String like this:

    class Liste {
      String Wort1;
      String Wort2;
    
      Liste({this.Wort1, this.Wort2});
      
      bool operator ==(other) {
        if (other is String) {
          return other == Wort1 || other == Wort2;
        } else {
          return false;
        }
      }
    }
    

    By the way, please don't name variables with first letter as capital.