在 Swift 数组中查找第一个元素匹配条件(例如 EKSource)
Find first element matching condition in Swift array (e.g. EKSource)
我想在 Swift 中找到 EKSourceType.Local
类型的第一个 EKSource
和 "single" 行表达式。这是我目前拥有的:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ [=11=].sourceType })
.indexOf(EKSourceType.Local)!]
是否有更好的方法(例如不使用 find
的通用版本映射 and/or)?
indexOf
的一个版本采用谓词闭包 - 使用它来查找第一个本地源的索引(如果存在),然后在 eventStore.sources
上使用该索引:
if let index = eventStore.sources.indexOf({ [=10=].sourceType == .Local }) {
let eventSourceForLocal = eventStore.sources[index]
}
或者,您可以通过 SequenceType
上的扩展添加通用 find
方法:
extension SequenceType {
func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
let eventSourceForLocal = eventStore.sources.find({ [=11=].sourceType == .Local })
(为什么这个还没有?)
我完全不明白你为什么要使用 map
。为什么不使用 filter
?然后你会得到所有的本地资源,但实际上可能只有一个,或者 none,你可以很容易地通过询问第一个(它将是 nil
如果没有的话):
let local = eventStore.sources.filter{[=10=].sourceType == .Local}.first
对于 Swift 3,您需要对上面 Nate 的回答做一些小改动。这是 Swift 3 版本:
public extension Sequence {
func find(predicate: (Iterator.Element) throws -> Bool) rethrows -> Iterator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
更改:SequenceType
> Sequence
、Self.Generator.Element
> Iterator.Element
或者在 Swift3 中你可以使用:
let local = eventStore.sources.first(where: {[=10=].sourceType == .Local})
让我们尝试一些更实用的东西:
let arr = [0,1,2,3]
let result = arr.lazy.map { print(""); return [=10=] }.first(where: { [=10=] == 2 })
print(result) // 3x then 2
这有什么好看的?
您可以在搜索时访问 element 或 i。而且它很实用。
Swift 4 解决方案还可以处理数组中没有符合条件的元素的情况:
if let firstMatch = yourArray.first{[=10=].id == lookupId} {
print("found it: \(firstMatch)")
} else {
print("nothing found :(")
}
Swift 5 如果你想从模型数组中找出然后指定 $0.keyTofound 否则使用 $0
if let index = listArray.firstIndex(where: { [=10=].id == lookupId }) {
print("Found at \(index)")
} else {
print("Not found")
}
我想在 Swift 中找到 EKSourceType.Local
类型的第一个 EKSource
和 "single" 行表达式。这是我目前拥有的:
let eventSourceForLocal =
eventStore.sources[eventStore.sources.map({ [=11=].sourceType })
.indexOf(EKSourceType.Local)!]
是否有更好的方法(例如不使用 find
的通用版本映射 and/or)?
indexOf
的一个版本采用谓词闭包 - 使用它来查找第一个本地源的索引(如果存在),然后在 eventStore.sources
上使用该索引:
if let index = eventStore.sources.indexOf({ [=10=].sourceType == .Local }) {
let eventSourceForLocal = eventStore.sources[index]
}
或者,您可以通过 SequenceType
上的扩展添加通用 find
方法:
extension SequenceType {
func find(@noescape predicate: (Self.Generator.Element) throws -> Bool) rethrows -> Self.Generator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
let eventSourceForLocal = eventStore.sources.find({ [=11=].sourceType == .Local })
(为什么这个还没有?)
我完全不明白你为什么要使用 map
。为什么不使用 filter
?然后你会得到所有的本地资源,但实际上可能只有一个,或者 none,你可以很容易地通过询问第一个(它将是 nil
如果没有的话):
let local = eventStore.sources.filter{[=10=].sourceType == .Local}.first
对于 Swift 3,您需要对上面 Nate 的回答做一些小改动。这是 Swift 3 版本:
public extension Sequence {
func find(predicate: (Iterator.Element) throws -> Bool) rethrows -> Iterator.Element? {
for element in self {
if try predicate(element) {
return element
}
}
return nil
}
}
更改:SequenceType
> Sequence
、Self.Generator.Element
> Iterator.Element
或者在 Swift3 中你可以使用:
let local = eventStore.sources.first(where: {[=10=].sourceType == .Local})
让我们尝试一些更实用的东西:
let arr = [0,1,2,3]
let result = arr.lazy.map { print(""); return [=10=] }.first(where: { [=10=] == 2 })
print(result) // 3x then 2
这有什么好看的?
您可以在搜索时访问 element 或 i。而且它很实用。
Swift 4 解决方案还可以处理数组中没有符合条件的元素的情况:
if let firstMatch = yourArray.first{[=10=].id == lookupId} {
print("found it: \(firstMatch)")
} else {
print("nothing found :(")
}
Swift 5 如果你想从模型数组中找出然后指定 $0.keyTofound 否则使用 $0
if let index = listArray.firstIndex(where: { [=10=].id == lookupId }) {
print("Found at \(index)")
} else {
print("Not found")
}