Flutter: How to search a 'set' for an object based on the object's field value

3,928

To summarise then following Kris' comments, to return a bool from a query of an object's field, 'contains' cannot be used. Instead you could use where or maybe other methods from the Set class that adopt a test element eg (bool test(E element), { E orElse() }) → E) (https://api.dartlang.org/stable/2.6.1/dart-core/Set-class.html), and add a ternary operator to return the desired bool result.

void main() {
  print(Check().contains());
}

class MyClass {
  final String a;
  final int b;
  final double c;
  MyClass({this.a, this.b, this.c});
}

class Check{
   Set<MyClass> mSet = new Set<MyClass>();
   bool contains() {
     mSet.add(new MyClass(a: "someString1", b:3, c:2.0));
     mSet.add(new MyClass(a: "someString2", b:1, c:3.0));
     mSet.add(new MyClass(a: "someString3", b:2, c:1.0));
     return mSet.where((item) => item.a  == "someString1").length > 0;
   }
}

>>true

EDIT: after trying a few other 'test element' methods (eg firstWhere and lastWhere) it seems 'where' is the only method I've tested that doesn't fail if there is no match. If you use the others you need a catch then to return false. I've stuck with 'where' and a ternary for the cleanest solution as per the revised code above. If only 'contains' included a test element.

Share:
3,928
plam
Author by

plam

Updated on December 15, 2022

Comments

  • plam
    plam over 1 year

    As per the title how do I search a 'Set' for an object by the objects field value. The following is incorrect code but hopefully gives the idea. The closest i could find was How to search for an object in List<object> having its field value but the same doesn't seem to apply.

    class MyClass {
      final String a;
      final int b;
      final double c;
      MyClass({this.a, this.b, this.c});
    }
    
    class Check{
       Set<MyClass> mSet = new Set<MyClass>();
       contains() {
         mSet.add(new MyClass(a: "someString1", b:3, c:2.0));
         mSet.add(new MyClass(a: "someString2", b:1, c:3.0));
         mSet.add(new MyClass(a: "someString3", b:2, c:1.0));
         //following is not correct, but to get the idea...
         print(mSet.contains((item) => item.a == "someString1"));
         //need to return true
       }
    }
    
    >FALSE
    

    Same question might apply to Set.where, Set.remove ...etc for instance if I add

    var b = mSet.where((item) => item.a == "someString1");
    

    b results in an iterable with all values of the Set.

  • plam
    plam over 4 years
    Thanks Kris, so really it's just that "contains" doesn't include a conditional option. I might delete this post given it is a simple overlook on my behalf. Thanks