У меня ошибка в «фильтре», но не в » для » ..ПОЧЕМУ??(ошибка: компилятор не может ввести-проверить это выражение в разумные сроки’)

#swift

Вопрос:

Я новичок в программировании на swift. Я пытаюсь получить строку с единственными буквами(«a-z», «A-Z»), цифрами(«0-9») и «-«, «_», «*».

когда я впервые попробовал этот код

 var new_id = "abc123##%%.."
    new_id.filter { ($0 >= "a" amp;amp; $0 <= "z") || ($0 >= "0" amp;amp; $0 <= "9") || $0 == "-" || $0 == "_" || $0 == "." }
 

Я получил эту ошибку

ошибка: компилятору не удается ввести-проверьте это выражение в разумное время; попробуйте разбить выражение на отдельные вложенные выражения

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

 
for i in 0..<new_id.count {
    let ch: Character = new_id[new_id.index(new_id.startIndex, offsetBy: i)]
    if ( (ch >= "a" amp;amp; ch <= "z") || (ch >= "0" amp;amp; ch <= "9") || ch == "-" || ch == "_" || ch == "." ) {
        new_new_id.append(ch)
    }
}
 

Тогда в чем разница между этими двумя кодами? Я думал, что приведенная выше функция «фильтр» работает так же, как и приведенный ниже код с оператором «для»
.

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

1. В первом случае new_id не является массивом.

2. не прямой ответ на ваш вопрос, но вы можете просто использовать { "a"..."z" ~= $0 || "0"..."9" ~= $0 || $0 == "-" || $0 == "_" || $0 == "." } или даже проще { "a"..."z" ~= $0 || "0"..."9" ~= $0 || "-_.".contains("$0") }

3. Вероятно, это связано с некоторыми неясными деталями реализации в компиляторе Swift. Обработка закрытия одного выражения, вероятно , требует большего количества шагов. Если вы просто измените filter закрытие на if ... { return true } else { return false } , это тоже сработает.

4. @Sweeper Я думаю, что это связано с тем фактом, что если есть одна строка (закрытие), она пытается вывести результирующий тип

5. используйте регрессию вместо фильтра

Ответ №1:

         let newString = "Hello123..H##^^%%"
        
        
        let StringData = newString.filter({$0.isLetter})
        let NumericData = newString.filter({$0.isNumber})
        let caseData = newString.filter({$0 == "_" || $0 == "-" || $0 == "."})
        
        
        
        let ChekedData = newString.filter({$0.isNumber || $0.isLetter || $0 == "_" || $0 == "-" || $0 == "."})
        
        print(StringData)
        print(NumericData)
        print(caseData)
        
        print(ChekedData) ```
 

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

1. Спасибо за предложение. Но в чем разница для компилятора swift между $0.isNumber закрытием одного выражения и (ch >= "a" amp;amp; ch <= "z") в закрытии одного выражения?

2. isNumber Проверьте, является ли $0 (символ в строке) числом или нет… если это число, оно сохранит его