Как получить доступ к значению на карте (через список карт) и преобразовать эти значения в отображение списка

#flutter #google-cloud-firestore

#flutter #google-cloud-firestore

Вопрос:

Я хотел бы получить число из списка карт и суммировать его значения. Я думаю, что я застрял в строке кода, где я определяю, где находится «timerSec» на карте, чтобы поместить его в список перед суммированием. Я продолжаю получать сообщение «Класс ‘UserAttempt’ не имеет метода экземпляра ‘[]'». ошибка

Я проверил, что список пользовательских попыток возвращается из firebase. Каждая попытка пользователя содержит узел IdealPosition, который содержит значение «timerSec» в значении. Из приведенных ниже результатов я бы ожидал результат 13.

 -UserAttempt1 (level 1 node)
--IdealPosition (level 2 node)
---timerSec: 3 (int value)
-UserAttempt2 (level 1 node)
--IdealPosition (level 2 node)
---timerSec: 4 (int value)
-UserAttempt3 (level 1 node)
--IdealPosition (level 2 node)
---timerSec: 6 (int value)
  

Я вызываю функцию getUserAttempts() (которая, как я проверяю в отладчике, заполняет _userAttempts списком пользовательских запросов). В следующей строке следующей функции я, похоже, не могу понять, как найти timerSec на карте userAttempt, чтобы поместить список в sum. Я продолжаю получать сообщение о том, что «Класс ‘UserAttempt’ не имеет метода экземпляра ‘[]'». ошибка.

 Future<int> getTotalAttemptTime() async {
  var resu<
  var _userAttempts = await getUserAttempts();
  timerSecList = _userAttempts.map<int>((m) => m['UserAttempt']['idealPosition']['timerSec'] as int).toList();
  result = timerSecList.reduce((sum, element) => sum   element);
  print("OMG!!!! $result");
  return resu<
}

  

Я также видел другие примеры, которые я взломал и не смог заставить работать.

 _userAttempts.entries.map((e) => timerSecList.add(e.value));
_userAttempts.map.forEach((_userAttempt.idealPosition.timerSec) => as List);
  

Вот где я нахожусь в коде

 class UserAttemptsManager extends ChangeNotifier{
  final _fsCrudManager = locator<FstoreCrudManagerUserSession>();

  List<UserAttempt> _userAttempts = [];
  UserAttempt _userAttempt;
  List<IdealPosition> _idealPositions;
  IdealPosition _idealPosition;
  List<int> timerSecList = [];

  getUserAttempts() async {
    _userAttempts =  await _fsCrudManager.fetchPositions();
    return _userAttempts;
  }

  Future<int> getTotalAttemptTime() async {
   var resu<
   var _userAttempts = await getUserAttempts();
   timerSecList = _userAttempts.map<int>((m) => m['UserAttempt']['idealPosition']['timerSec'] as int).toList();
  result = timerSecList.reduce((sum, element) => sum   element);
   print("OMG!!!! $result");
   return resu<
  }

}

  

Вот соответствующие классы

 class UserAttempt {
  String id;
  double score;
  DateTime dateTime;
  IdealPosition idealPosition;
  List<UserAttemptItem> userAttemptLog;

  UserAttempt({this.id, this.dateTime,this.userAttemptLog, this.score, this.idealPosition});

  // from firestore to map
  factory UserAttempt.fromJson(Map<String, dynamic> json, String id){
    //var _id = id;
    if (json['userAttemptLog'] != null) {
      var userAttemptLogObjsJson = json['userAttemptLog'] as List;
      List<UserAttemptItem> _userAttemptLog = userAttemptLogObjsJson.map((userAttemptLogJson) => UserAttemptItem.fromJson(userAttemptLogJson, id)).toList();

      return UserAttempt(
        id: id = id,
        score: json['score'],
        dateTime: json['dateTime'].toDate(),
        idealPosition: IdealPosition.fromMap(json['idealPosition'], id),
        userAttemptLog: _userAttemptLog
      );
    } else {
      return UserAttempt(
        id: id = id,
        dateTime: json['dateTime'].toDate(),
        score: json['score'],
        idealPosition: IdealPosition.fromMap(json['idealPosition'], id),
      );
    }
  }

  @override
  String toString() {
    return '{ ${this.id}, ${this.userAttemptLog} }';
  }

  // to firestore
  Map<String, dynamic> toJson() {
    //final Map<String, dynamic> data = new Map<String, dynamic>();
    List<Map> _userAttemptLog = this.userAttemptLog != null ? this.userAttemptLog.map((i) => i.toJson()).toList() : null;
    Map idealPosition = this.idealPosition != null ? this.idealPosition.toJson() : null;

    return {
      //'id': id,
      'score': score,
      'dateTime': DateTime.now(),
      'idealPosition': idealPosition,
      'userAttemptLog': _userAttemptLog,

    };
  }
}

  

также один для идеальной позиции (пока не используя UserAttemptLog)

 class IdealPosition {
  String id;
  String type;
  String name;
  int timerSec;
  int orientation;

  IdealPosition({
    this.id,
    this.type,
    this.name,
    this.timerSec,
    this.orientation,
  });

  // From firebase
  IdealPosition.fromMap(Map snapshot, String id)
      :
        id = id ?? '',
        type = snapshot['type'] ?? 'undefined',
        name = snapshot['name'] ?? 'Undefined',
        timerSec = snapshot['timerSec'] ?? 0,
        orientation = snapshot['orientation'] ?? 2;

  // To firebase
  toJson() {
    return {
      "name": name,
      "timerSec": timerSec,
      "type": type,
      "orientation": orientation,
    };
  }
}

  

Комментарии:

1. Я изменил var _userAttempts = await getUserAttempts(); на этот `List<UserAttempt> _userAttempts = await getUserAttempts();’ и избавился от ошибки после внесения предложенных изменений ниже

Ответ №1:

 final timerSecSum = _userAttempts.map((m) => m.idealPosition.timerSec).reduce((a,b) => a   b);
  

Комментарии:

1. Неплохо. Спасибо. Я вижу, вы добавили вторую функцию для суммирования. Я смогу использовать этот шаблон в другом месте. Приятно видеть, как это работает и насколько это чисто. Также, пожалуйста, обратите внимание, что у меня пока нет репутации, чтобы выбрать ответ в качестве ответа (или действительно что-либо сделать).

2. Была возможность поменять строку и получила следующую ошибку type '(dynamic) => dynamic' is not a subtype of type '(UserAttempt) => int' of 'f'

3. Удалите <int> перед map

4. Ответы, содержащие только код, не рекомендуется использовать при переполнении стека, поскольку они не объясняют, как это решает проблему. Пожалуйста, отредактируйте свой ответ, чтобы объяснить, что делает этот код и как он отвечает на вопрос, чтобы он был полезен другим пользователям с аналогичными проблемами.

Ответ №2:

Измените эту строку:

    timerSecList = _userAttempts.map<int>((m) => m['UserAttempt']['idealPosition']['timerSec'] as int).toList();
  

к этому:

 timerSecList = _userAttempts.map<int>((m) => m.idealPosition.timerSec).toList();
  

Комментарии:

1. Это имеет смысл! Я не смог правильно выполнить эту часть. Большое вам спасибо. Я смогу попробовать это позже вечером. Также, пожалуйста, обратите внимание, что у меня нет репутации, чтобы выбрать ответ в качестве ответа (или действительно что-либо сделать)

2. Была возможность поменять строку и получила следующую ошибку type '(dynamic) => dynamic' is not a subtype of type '(UserAttempt) => int' of 'f'

3. Удалите <int> перед map