Filter,Closure,for循环的功能语法版本,具有多个条件

时间:2016-11-17 21:15:27

标签: swift functional-programming

我试图学习函数式编程的一些想法,因为它们存在于Swift中。

recent question中,Rickster(大师)显示它有多好。

来自:

var voiceToUse: AVSpeechSynthesisVoice?
let voices = AVSpeechSynthesisVoice.speechVoices()         
for voice in voices {
            if voice.name == "Arthur"
            {
                voiceToUse = voice
            }
        }

到此:

let voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Arthur" }).first

现在我想知道这种技术如何应用​​于有多个标准的问题。这种功能风格可以做到这一点:

var voiceToUse: AVSpeechSynthesisVoice?
let voices = AVSpeechSynthesisVoice.speechVoices()     
for voice in voices {
                    if voice.name == "Samantha (Enhanced)"  && voice.quality == .enhanced
                    {
                        voiceToUse = voice
                    }
                }

3 个答案:

答案 0 :(得分:4)

您的单个​​条件表达式在闭包语法中使用两个快捷方式:

1 - 如果只有一个表达式,则会隐式返回它的值

2 - $0指的是第一个参数 - 编译器推断出它的类型

因此,您可以将表达式扩展为多个子句,只要它仍然是单个表达式:

let voiceToUse = AVSpeechSynthesisVoice.speechVoices().filter({ $0.name == "Samantha (Enhanced)"  && $0.quality == .enhanced }).first

没有两个快捷方式的等价物是:

let voiceToUseB = AVSpeechSynthesisVoice.speechVoices().filter(
{ voice in
    let found:Bool = voice.name == "Samantha (Enhanced)" && voice.quality == .enhanced
    return found
}).first

答案 1 :(得分:2)

请注意,这会返回AVSpeechSynthesisVoice?的值,因此请务必考虑到这一点。

let voiceToUse = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.name == "Samantha (Enhanced)" && $0.quality == .enhanced })

答案 2 :(得分:1)

  

如果您希望数组的第一个元素满足条件   用这个。

if let voiceToUse = AVSpeechSynthesisVoice.speechVoices().first(where: {
        $0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
    }){

      //use the voiceTouse Variable

    }
  

如果你想要数组的最后一个元素满足   标准使用此。

if let voiceToUse = AVSpeechSynthesisVoice.speechVoices().reversed().first(where: {
       $0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
    }){

      //use the voiceTouse Variable

    }
  

是的,我们可以使用看守......

如果不满足一个或多个条件,则使用保护语句将程序控制转移到范围之外。 在这个例子中,如果条件不满足,即AVSpeechSynthesisVoice.speechVoices()中没有满足条件的元素,则guard let将把程序控制转移出check函数,否则如果AVSpeechSynthesisVoice中有一些元素。满足条件的speechVoices(),程序控制转到guard let语句后的下一行

func check(){
guard let voiceToUse =  AVSpeechSynthesisVoice.speechVoices().first(where: {
   $0.name == "Samantha (Enhanced)" && $0.quality == .enhanced
})else{
    return
}
 //use the voiceToUseVariable

}

check()