Фильтрация массива из содержимого другого массива

#arrays #swift #xcode #sorting #filter

Вопрос:

У меня есть 2 массива, оба со строками.

 let exclude = ["text 1", "text 2", "APP", "John"]
let array2 = ["this is text 1", "This is text 2", "This App is under development", "John is working on this project", "This is great"]
 

Я пытаюсь отфильтровать любой текст, который содержится в exclude из array2, чувствительный к регистру.
Итак, в этом примере он должен выводить "This is great"

Вместо того, чтобы использовать несколько строк для каждого фильтра, например: let filter = array2.filter{!$0.contains("APP")}

Я пробовал: var filter = array2.filter({exclude.contains($0)}) но он не фильтрует. Любые советы будут с благодарностью

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

1. let filtered = array2.filter { aString in return !exclude.contains(where: { anExcludedString in return aString.range(of: anExcludedString, options: .caseInsensitive) != nil }) } с явным return и не $0 должно делать трюк.

2. Проблема с вашей текущей логикой: вы не тестируете регистр без учета регистра, и вы используете contains массив, поэтому вы ожидаете ПОЛНОГО равенства.

3. @Larme спасибо вам за разъяснение и быстрый ответ. Я попытался поискать похожие ответы, но ничего не смог найти, поэтому опубликовал. Теперь я вижу проблему, и теперь я понимаю. Спасибо вам еще раз .. кстати, вы можете опубликовать это как ответ, чтобы я мог пометить его?

Ответ №1:

С «явным» return и «нет $0 » .

 let filtered = array2.filter { aString in
    return !exclude.contains(where: { anExcludedString in
        return aString.range(of: anExcludedString, options: .caseInsensitive) != nil
    })
}
 

Почему var filter = array2.filter({exclude.contains($0)}) не сработало?

  • Первая проблема:
    проверка без учета регистра отсутствует.
  • Второй вопрос:
    Вы используете contains() на a [String] , а не на a String . Таким образом, он ожидает полного равенства между двумя строками. Так что, если array2 бы это было ["APP"] так, это бы сработало.

Например, если бы у вас было:

 let exclude = ["text 1", "text 2", "APP", "John"]
let array2 = ["this is text 1", "This is text 2", "This App is under development", "John is working on this project", "This is great", "This APP is under development"]
let filtered = array2.filter { aString in
    return !exclude.contains(where: { anExcludedString in
        return aString.contains(anExcludedString)
    })
}
 

Тогда "This APP is under development" он был бы удален.

Теперь, возвращаясь к первоначальному ответу, способ проверки без учета регистра — использовать range(of:options:) .

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

1. Отличный ответ. Еще раз спасибо

2. Вы также можете использовать localizedStandardContains для поиска без учета регистра и диакритических знаков