Dart List - filter on sub type

2019-07-26 03:58发布

问题:

In my dart projects a construct occurs often in many contexts. For a List with types, that has child types, this code filters out the child types to a new list :

class A {
}

class AChild extends A {  
}

List<A> alist = [new A(), new AChild()];
List<AChild> aclist = alist.where((final A a) => a is AChild).
                            map((final A a) => a as AChild).toList();

Not a big deal, things works ok. So I just search some polish. Could this be replaced with a function or something more compact? Have tried to write a function with a List and a generic type, but don't get the is to accept this.

回答1:

Not sure if you would consider this shorter. If you use this pattern often, it might be:

class CheckType<T> {
  bool isT(dynamic v) => v is T;

  T as(dynamic v) => v as T;
}

main() {
  final ct = new CheckType<AChild>();
  List<A> alist = [new A(), new AChild()];
  List<AChild> aclist = new List<AChild>.from(alist.where(ct.isT).(ct.as));
}

DartPad example



回答2:

Based on the tip from Günter, that instead of a function use a tool class. If occurring often the filter class can be put as constant in the project, so nice. Got following:

class A {}

class AChild extends A {}

class TypeFilter<T, Z>{

  const TypeFilter();

  List<T> list(List<Z> lz){
    return lz.where((final Z z) => z is T)
        .map((final Z z) => z as T).toList();
  }
}

main(List<String> args) {
  const TypeFilter filterAChild = const TypeFilter<AChild, A>();

  List<A> alist = [new A(), new AChild()];
  List<AChild> aclist = filterAChild.list(alist);
  print(aclist);
}


标签: dart