Swift是否有类似_.findWhere的内容中的内容?
我有一个类型为struct的数组,T想检查array是否包含name属性等于的struct对象Foo。
尝试使用 find(),filter()但它们仅适用于基本类型,例如String或Int。引发有关不符合Equitable协议之类的错误。
Swift是否有类似_.findWhere的内容中的内容?
我有一个类型为struct的数组,T想检查array是否包含name属性等于的struct对象Foo。
尝试使用 find(),filter()但它们仅适用于基本类型,例如String或Int。引发有关不符合Equitable协议之类的错误。
Answers:
FWIW,如果您不想使用自定义功能或扩展名,则可以:
let array = [ .... ]
if let found = find(array.map({ $0.name }), "Foo") {
    let obj = array[found]
}
name首先生成数组,然后find从中。
如果阵列很大,则可能需要执行以下操作:
if let found = find(lazy(array).map({ $0.name }), "Foo") {
    let obj = array[found]
}
或许:
if let found = find(lazy(array).map({ $0.name == "Foo" }), true) {
    let obj = array[found]
}
              SWIFT 5
检查元素是否存在
if array.contains(where: {$0.name == "foo"}) {
   // it exists, do something
} else {
   //item could not be found
}
获取元素
if let foo = array.first(where: {$0.name == "foo"}) {
   // do something with foo
} else {
   // item could not be found
}
获取元素及其偏移量
if let foo = array.enumerated().first(where: {$0.element.name == "foo"}) {
   // do something with foo.offset and foo.element
} else {
   // item could not be found
}
获取偏移
if let fooOffset = array.firstIndex(where: {$0.name == "foo"}) {
    // do something with fooOffset
} else {
    // item could not be found
}
              $0.name == "foo"执行一项操作并   $0.name == "boo"  执行另一项操作
                    您可以使用谓词index上可用的方法Array(请参阅此处的Apple文档)。
func index(where predicate: (Element) throws -> Bool) rethrows -> Int?
对于您的特定示例,这将是:
斯威夫特5.0
if let i = array.firstIndex(where: { $0.name == "Foo" }) {
    return array[i]
}
斯威夫特3.0
if let i = array.index(where: { $0.name == Foo }) {
    return array[i]
}
雨燕2.0
if let i = array.indexOf({ $0.name == Foo }) {
    return array[i]
}
              迅捷3
如果需要该对象,请使用:
array.first{$0.name == "Foo"}
(如果有多个名为“ Foo” first的对象,则将以未指定的顺序返回第一个对象)
array.first {$0.name == "Foo"}
                    array.first(where: {$0.name == "Foo"})
                    您可以过滤数组,然后选择第一个元素,如“ 在数组中查找带有属性的对象”中所示。
或者您定义自定义扩展
extension Array {
    // Returns the first element satisfying the predicate, or `nil`
    // if there is no matching element.
    func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? {
        for item in self {
            if predicate(item) {
                return item // found
            }
        }
        return nil // not found
    }
}
用法示例:
struct T {
    var name : String
}
let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")]
if let item = array.findFirstMatching( { $0.name == "foo" } ) {
    // item is the first matching array element
} else {
    // not found
}
在Swift 3中,您可以使用现有first(where:)方法(如注释中所述):
if let item = array.first(where: { $0.name == "foo" }) {
    // item is the first matching array element
} else {
    // not found
}
              array.lazy.filter( predicate ).first呢?.lazy对于小型阵列的效率如何?
                    filter总是复杂的,O(n)而在情况中findFirstMatching,只有在最坏的情况下(当您要查找的元素是数组中的最后一个或根本不在数组中时),它总是很复杂的。2. filter创建一个全新的过滤元素数组,而findFirstMatching刚刚返回所请求的元素。
                    斯威夫特3.0
if let index = array.index(where: { $0.name == "Foo" }) {
    return array[index]
}
斯威夫特2.1
swift 2.1现在支持对象属性过滤。您可以根据struct或class的任何值过滤数组,这是一个示例
for myObj in myObjList where myObj.name == "foo" {
 //object with name is foo
}
要么
for myObj in myObjList where myObj.Id > 10 {
 //objects with Id is greater than 10
}
              Swift 2或更高版本
您可以合并indexOf并map在一行中编写“查找元素”功能。
let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")]
let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] }
print(foundValue) // Prints "T(name: "Foo")"
使用filter+ first看起来更干净,但是会filter评估数组中的所有元素。indexOf+ map看起来很复杂,但是当找到数组中的第一个匹配项时,评估就会停止。两种方法都各有利弊。
用途contains:
var yourItem:YourType!
if contains(yourArray, item){
    yourItem = item
}
或者,您可以尝试在注释中尝试Martin指出的内容,然后filter再尝试一次:在Array中查找具有Property的对象。
item与数组中的项具有相同的类型。但是,我所拥有的只是的标题view.annotation.title。我需要按此标题比较数组中的项目。
                    if contains(yourArray, view.annotation.title) { // code goes here }。
                    斯威夫特3:
您可以使用Swifts内置功能在数组中查找自定义对象。
首先,您必须确保您的自定义对象符合:Equatable protocol。
class Person : Equatable { //<--- Add Equatable protocol
    let name: String
    var age: Int
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    //Add Equatable functionality:
    static func == (lhs: Person, rhs: Person) -> Bool {
        return (lhs.name == rhs.name)
    }
}
将Equatable功能添加到对象后,Swift现在将向您显示可在数组上使用的其他属性:
//create new array and populate with objects:
let p1 = Person(name: "Paul", age: 20)
let p2 = Person(name: "Mike", age: 22)
let p3 = Person(name: "Jane", age: 33)
var people = [Person]([p1,p2,p3])
//find index by object:
let index = people.index(of: p2)! //finds Index of Mike
//remove item by index:
people.remove(at: index) //removes Mike from array