в Swift 4 избегайте принудительной разворачивания внутри крышки фильтра - PullRequest
0 голосов
/ 25 августа 2018

Я пытаюсь отфильтровать массив [String?] С помощью "abc".

// keysForAutoComplete: [String?]
let tempFilteredResult = keysForAutoComplete.filter { ($0?.contains("abc"))! }

Как можно избежать принудительного развертывания внутри замыкания?Я знаю о заявлениях let и guard let, но не совсем уверен, как их применять здесь?

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Вы можете использовать оператор compactMap для удаления значений nil и оставить свой массив как тип [String], так что каждый элемент будет необязательным значением.После этого вы можете использовать filter для нового массива.Таким образом, вам не нужно беспокоиться о нулевых значениях, тогда распаковка не нужна.

let keysForAutoComplete = ["abc", "ab", nil, "bca", "abcd"]
let tempFilteredResult = keysForAutoComplete.compactMap{$0}.filter{$0.contains("abc")}
0 голосов
/ 25 августа 2018

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

let tempFilteredResult = keysForAutoComplete.filter { $0?.contains("abc") == true }

или с помощью оператора nil coalescing ??, чтобы развернуть результат:

let tempFilteredResult = keysForAutoComplete.filter { $0?.contains("abc") ?? false }

или с помощью оператора nil коалесцирующий ?? для разворачивания ввода:

let tempFilteredResult = keysForAutoComplete.filter { ($0 ?? "").contains("abc") }

Объяснение:

$0?.contains("abc") использует необязательное сцепление , и в результате получается Bool?, равный nil, если элемент nil или Optional(true) или Optional(false) в зависимости от того, Stringсодержит "abc".Вы можете сравнить Bool? с Bool, поэтому сравнение с true вернет true только тогда, когда есть String, который содержит "abc".

nil coalescingоператор разворачивает значение, если оно не nil, или заменяет его на предоставленное значение по умолчанию, если оно nil.Поскольку вы хотите, чтобы элемент nil возвращал false для сравнения, способ безопасного развертывания заключается в использовании ?? false.

. В третьем примере оператор объединения nil разворачивает значение из tempFilteredResult, заменяя его пустой строкой "", если оно равно nil.


Если вы хотите, чтобы результат был [String], вы можете использовать compactMap вместе с оператором ?: для генерации массива [String]:

let tempFilteredResult = keysForAutoComplete.compactMap { $0?.contains("abc") == true ? $0 : nil }

Объяснение:

Здесь, ?: используется для возврата исходного значения, если оно содержит "abc" или nil, если его нет.compactMap затем удаляет значения nil и разворачивает String?, возвращая [String].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...