Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查字符串是否包含Swift中的可选字符串,但仅当它为';不是零_Swift - Fatal编程技术网

检查字符串是否包含Swift中的可选字符串,但仅当它为';不是零

检查字符串是否包含Swift中的可选字符串,但仅当它为';不是零,swift,Swift,我想向处理字符串列表的函数添加一个可选的“filter”参数。如果筛选器为nil,我希望处理所有字符串,否则我只希望处理包含筛选器的字符串。大致: func process(items: [String], filter: String?) { for item in items { if filter == nil || item.contains(filter) { // Do something with item } } } typechecker抱

我想向处理字符串列表的函数添加一个可选的“filter”参数。如果筛选器为
nil
,我希望处理所有字符串,否则我只希望处理包含筛选器的字符串。大致:

func process(items: [String], filter: String?) {
  for item in items {
    if filter == nil || item.contains(filter) {
      // Do something with item
    }
  }
}
typechecker抱怨将筛选器传递到
contains
,因为它是可选的,但是
contains
使用
字符串。我当然可以强行打开,但那看起来很难看。上面的代码将用Kotlin编译,因为它会去掉可选的,但是用Swift表达这一点的惯用方式是什么呢


谢谢

可选项上有一个
映射
,仅当可选项不是
nil
时才执行提供的闭包。如果
map
返回
nil
,则可以使用
map
和nil合并运算符
??
提供
true
的默认值,因为
过滤器是
nil

func process(items: [String], filter: String?) {
  for item in items {
    if filter.map(item.contains) ?? true {
      // process item
    }
  }
}

Optional上有一个
map
,仅当可选项不是
nil
时才执行提供的闭包。如果
map
返回
nil
,则可以使用
map
和nil合并运算符
??
提供
true
的默认值,因为
过滤器是
nil

func process(items: [String], filter: String?) {
  for item in items {
    if filter.map(item.contains) ?? true {
      // process item
    }
  }
}
这里的关键是(并且将一直是)零聚结操作符。如果可选值不是
nil
,则可以安全地展开它,但如果它是
nil
,则可以替换另一个值

然而,这个问题的问题是,它以一种不坚定的方式出现。您永远不会编写接受可选字符串的筛选函数。您可以编写一个过滤函数,该函数采用可选的过滤函数!您希望允许任何类型的数组和任何过滤函数,而不是将调用者限制为
包含
和字符串。这是编写此函数的快捷方式

当我们在做这个时,函数也不应该预先决定对数组的成员做了什么。这应该是调用方传入的另一个函数

因此,我们最终对目标做出了更一般、更迅速的陈述:

func process<T>(_ arr: [T],
                     filtering filterPred: ((T)->Bool)? = nil,
                     processing processPred: ((T)->Void)) {
    // ...
}
非常好!但是我们忽略了处理
过滤
函数。让我们来解决这个问题。显然,这是橡胶与道路的交汇点。同样清楚的是,这是一个要传递到
过滤器中的函数。但是,我们只能在它不是
nil
的情况下通过展开来实现这一点。如果是
nil
,该怎么办?OP已经指定,在这种情况下,我们应该让所有元素通过过滤器

请考虑一个谓词函数,它将被传递到<代码>筛选器< /代码>。什么是让一切通过的功能?它是:

{ _ in true }
这就是在nil凝聚算子之后要做的!因此,这是完整的答案:

func process<T>(_ arr: [T],
                     filtering filterPred: ((T)->Bool)? = nil,
                     processing processPred: ((T)->Void)) {
    arr.filter(filterPred ?? { _ in true }).forEach(processPred)
}
这里的关键是(并且将一直是)零聚结操作符。如果可选值不是
nil
,则可以安全地展开它,但如果它是
nil
,则可以替换另一个值

然而,这个问题的问题是,它以一种不坚定的方式出现。您永远不会编写接受可选字符串的筛选函数。您可以编写一个过滤函数,该函数采用可选的过滤函数!您希望允许任何类型的数组和任何过滤函数,而不是将调用者限制为
包含
和字符串。这是编写此函数的快捷方式

当我们在做这个时,函数也不应该预先决定对数组的成员做了什么。这应该是调用方传入的另一个函数

因此,我们最终对目标做出了更一般、更迅速的陈述:

func process<T>(_ arr: [T],
                     filtering filterPred: ((T)->Bool)? = nil,
                     processing processPred: ((T)->Void)) {
    // ...
}
非常好!但是我们忽略了处理
过滤
函数。让我们来解决这个问题。显然,这是橡胶与道路的交汇点。同样清楚的是,这是一个要传递到
过滤器中的函数。但是,我们只能在它不是
nil
的情况下通过展开来实现这一点。如果是
nil
,该怎么办?OP已经指定,在这种情况下,我们应该让所有元素通过过滤器

请考虑一个谓词函数,它将被传递到<代码>筛选器< /代码>。什么是让一切通过的功能?它是:

{ _ in true }
这就是在nil凝聚算子之后要做的!因此,这是完整的答案:

func process<T>(_ arr: [T],
                     filtering filterPred: ((T)->Bool)? = nil,
                     processing processPred: ((T)->Void)) {
    arr.filter(filterPred ?? { _ in true }).forEach(processPred)
}

谁说我想要一个
包含
过滤器,而不是前缀匹配?还是正则表达式过滤器?这似乎是一个错误的责任<代码>过程
应该关注
//对项目做些什么
。如果用户想要过滤输入,他们可以简单地
处理(items:input.filter{$0.contains(“foo”))
他们自己。我对你的帖子进行了澄清,但我没有否决任何人。请不要认为是我否定。@LukeSideWalker我们的回答不太正确good@aaronstacy我只是碰巧自己又遇到了这个问题。我现在真的理解了这个问题,瓦卡瓦马的回答很有道理。该说谁呢我想要一个
包含
过滤器,而不是前缀匹配?或正则表达式过滤器?这似乎是一个错误的责任。
过程
应该关注
//对项做些什么
。如果用户想要过滤输入,他们可以简单地
处理(items:input.filter{$0.contains(“foo”})
他们自己。我对你的帖子进行了澄清,但我没有否决任何人。请不要认为是我否定。@LukeSideWalker我们的回答不太正确good@aaronstacy我只是碰巧自己又遇到了这个问题。我现在真的理解了这个问题,瓦卡瓦马的回答很有道理。