Как применить оператор .filter к отдельным элементам CurrentValueSubject, который является массивом в Swift Combine?

#swift #swift5 #combine

#быстрый #стремительный 5 #объединить

Вопрос:

У меня есть CurrentValueSubject это целый массив ChatModelFirebase . Что я хочу сделать, это удалить все ChatModelFirebase модели, у которых есть поле статуса «отменено». Проблема в том, что когда я применяю .filter(..) оператор, он действует на весь массив, а не на отдельные элементы.

 var chatFirebaseModels: CurrentValueSubject<[ChatModelFirebase], Never> = CurrentValueSubject([])

chatFirebaseModels
    .filter({ (chatModelFireBaseArray) -> Bool in
        // I want individual array items, not chatModelFireBaseArray
        return false
    })
  

Вот как выглядит завершение кода:

введите описание изображения здесь

Вы можете видеть, что он .filter(..) применяется к [ChatModelFirebase] массиву, а не к отдельным ChatModelFirebase моделям.

Является ли ответ здесь простым использованием .flatMap(..) ? Мне любопытно, есть ли правильный способ использования .filter(...) , отсюда и мой вопрос.

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

1. Это зависит от того, хотите ли вы сохранить массив и фильтрующие элементы в их собственном массиве? -> использовать .map { $0.filter { ...} } . Хотите отфильтровать все отдельные элементы? -> использовать flatMap { $0 }.filter { ... } .

2. Я не уверен, понял ли я ваш вопрос. Цель состоит в том, чтобы удалить некоторые элементы в массиве, которые не соответствуют определенному логическому условию.

3. Мой вопрос касается результата вашего сопоставления фильтрации. Вы хотите в конечном итоге получить [ChatModelFirebase] (как вы сами предложили в своем вопросе, используя flatmap) или [[ChatModelFirebase]] (карта фильтр). Оба способа являются «правильными» в том смысле, что в конечном итоге они достигают одного и того же, но результирующий тип будет другим.

4. О, я понимаю. Просто хочу получить массив моделей, т. Е. [ChatModelFirebase] .

Ответ №1:

Вы можете либо использовать .map для возврата отфильтрованного массива:

 chatFirebaseModels
    .map { array in
       array.filter { element in
          // ... filter by element
       }
    }
  

Или использовать цепочку чистого объединения (хотя это кажется излишне сложным):

 chatFirebaseModels
   .flatMap { Publishers.Sequence(sequence: $0) }
   .filter { element in
      // ... filter by element
   }
   .collect()