Как правильно сгенерировать список из двух других списков в соответствии с условием в Flutter

#list #flutter

#Список #flutter

Вопрос:

Я пытаюсь сгенерировать список с именем selectedBooks на основе двух других списков:

Это первый список:

     List<Book> availableBooks = [
       Book(
        id: 1,
        isActive: false,
        name: "Tipo 1"
       ),
       Book(
        id: 2,
        isActive: false,
        name: "Tipo 2"
       ),
       Book(
        id: 3,
        isActive: false,
        name: "Tipo 3"
       ),
       Book(
        id: 4,
        isActive: false,
        name: "Tipo 4"
       ),
    ]
 

Это второй список:

     List<Book> allowedBooks = [
       Book(
        id: 1,
        isActive: true,
        name: "Tipo 1"
       ),
       Book(
        id: 3,
        isActive: true,
        name: "Tipo 3"
       ),
    ]
 

И это список, который я пытаюсь сгенерировать:

        selectedBooks = availableBooks
          .map((book) =>
              allowedBooks.contains(book.id)
                  ? Book(
                      id: book.id,
                      isActive: true,
                      name: book.name)
                  : Book(
                      id: book.id,
                      isActive: false,
                      name: book.name))
          .toList();
 

Поскольку разрешенные книги содержат идентификаторы 1 и 3, я ожидаю, что выбранные книги будут:

     List<Book> selectedBooks = [
       Book(
        id: 1,
        isActive: true,
        name: "Tipo 1"
       ),
       Book(
        id: 2,
        isActive: false,
        name: "Tipo 2"
       ),
       Book(
        id: 3,
        isActive: true,
        name: "Tipo 3"
       ),
       Book(
        id: 4,
        isActive: false,
        name: "Tipo 4"
       ),
    ]
 

Однако это не работает, потому что в selectedBooks для всех book.isActive установлено значение false.

Я предполагаю, что что-то работает не так, как ожидалось, в приведенном здесь условии:

 selectedBooks = availableBooks
          .map((book) =>
              allowedBooks.contains(book.id) ? ...
 

Есть какие-нибудь подсказки? Большое спасибо.

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

1. у вас есть operator== переопределенный в Book классе? он используется методом contains

2. Привет @pskink, нет, это не переопределено.

3. @pskink Я использую operator == в другом месте, поэтому я не думаю, что мне следует его переопределять. Могу ли я изменить условие для достижения результата по-другому, на ваш взгляд?

Ответ №1:

Вместо allowedBooks.contains(book.id) того, чтобы вы должны использовать allowedBooks.any((allowedBook) => allowedBook.id == book.id)

Ответ №2:

contains сравнивает весь объект целиком, попробуйте так

  List<Book> selectedBooks = availableBooks
          .map((book) => allowedBooks.singleWhere((it) => it.id == book.id, 
          orElse: () => null) != null ? Book(
                      id: book.id,
                      isActive: true,
                      name: book.name) : Book(
                      id: book.id,
                      isActive: false,
                      name: book.name)).toList();
 

Протестировано в dartpad.dev