accessing object values using variable as a key

2020-05-02 12:43发布

问题:

I'm trying to access a class value by using a variable previously defined in dart, but I keep getting the error the operator [] isn't defined for the class

In Javascript I would access an object value using a variable like this:

let movie = {
  movieTitle : 'Toy Story',
  actor: 'Tom Hanks'
}

let actorName = 'actor';
console.log(movie[actorName]); // <- what I'm trying to replicate in dart
// expected output: Tom Hanks

Here is what I've tried and is throwing that error

class Movie {
  String name;
  String actor;
  String producer;
}

void main() {
  var movieTitle = new Movie();
  movieTitle.name = 'Toy Story';
  movieTitle.actor = 'Tom Hanks';

  print(movieTitle.actor); <- prints out Tom Hanks as expected

  var actorName = 'actor';

  print(movieTitle[actorName]); <- throws error
}

I expect to be able to use a variable on the fly to access the value.

A trivial use case for me would be if I had a a list of Movie classes, where some actors and producers are null, I would like to filter on either non null actors or producer with a function like so:

List values = movieList.where((i) => i.actor != "null").toList(); // returns all Movies in movieList where the actor value isn't the string "null"

var actorIsNull = 'actor';

List values = movieList.where((i) => i[actorisNull] != "null").toList(); // throws error

回答1:

You cannot access class members by a string containing their name. (Except with mirrors - outside the scope of this answer.)

You could remove the class altogether and just use a Map<String, String>.

Map<String, String> movie = {
  'movieTitle': 'Toy Story',
  'actor': 'Tom Hanks',
}

You could add some bool methods on the class.

bool hasNoActor() => actor == null;
...
List values = movieList.where((m) => !m.hasNoActor()).toList();

Or, you could pass a lambda to your mapper.

  Movie movieTitle = Movie()
    ..name = 'Toy Story'
    ..actor = 'Tom Hanks';

  Function hasActor = (Movie m) => m.actor != null;
  List values = movieList.where(hasActor).toList();


标签: dart