contain
、include
或has
的建议,在书中快速搜索也没有结果。有什么想法可以检查这个吗?我知道有一个方法find
可以返回索引号,但是否有像Ruby的#include?
那样返回布尔值的方法?
我需要的示例:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
Swift 2、3、4、5:
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
是协议扩展方法,属于SequenceType
(用于具有Equatable
元素的序列),而不是像早期版本中的全局方法。
备注:
contains()
方法要求序列元素采用Equatable
协议,做比较,请参见例如Andrews's answer。NSObject
子类的实例,则必须重写isEqual:
,请参见NSObject subclass in Swift: hash vs hashValue, isEqual vs ==。contains()
方法,不需要元素是可比较的,并且接受谓词作为参数,例如请参见Shorthand to test if an object exists in an array for Swift?。Swift旧版本:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
Equatable
协议(Dictionary<String, AnyObject>
不符合)。contains()
还有一种带谓词的变体(参见 https://dev59.com/e10b5IYBdhLWcg3wCtXY),也许你可以使用它,例如:`if contains(array, { $0 == dict } ) ...` - Martin R如果您在这里寻找如何从数组中查找并删除对象的方法:
Swift 1
if let index = find(itemList, item) {
itemList.removeAtIndex(index)
}
Swift 2
if let index = itemList.indexOf(item) {
itemList.removeAtIndex(index)
}
Swift 3,4
if let index = itemList.index(of: item) {
itemList.remove(at: index)
}
Swift 5.2
if let index = itemList.firstIndex(of: item) {
itemList.remove(at: index)
}
更新为Swift 2+
请注意,从Swift 3(甚至2)开始,下面的扩展不再必要,因为全局contains
函数已经成为Array
上一对扩展方法,允许您执行以下任一操作:
let a = [ 1, 2, 3, 4 ]
a.contains(2) // => true, only usable if Element : Equatable
a.contains { $0 < 1 } // => false
Swift 1 的历史解决方案:
使用以下扩展:(更新至 Swift 5.2)
extension Array {
func contains<T>(obj: T) -> Bool where T: Equatable {
return !self.filter({$0 as? T == obj}).isEmpty
}
}
用法:
array.contains(1)
contains
被添加到了语言中。 - David Berrystruct Cup: Equatable {
let filled:Bool
}
static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
return lhs.filled == rhs.filled
}
那么你可以执行:
cupArray.contains(myCup)
提示:重载运算符应该放在全局层次,而不是在你的类/结构体内部。
我使用了过滤器。
let results = elements.filter { el in el == 5 }
if results.count > 0 {
// any matching items are in results
} else {
// not found
}
如果您愿意,可以将其压缩为
if elements.filter({ el in el == 5 }).count > 0 {
}
希望这有所帮助。
Swift 2更新
默认实现万岁!
if elements.contains(5) {
// any matching items are in results
} else {
// not found
}
(Swift 3)
如果意图是:
则作为蓝本化的 Sequence
,与 contains(_:)
的另一种选择是使用 Sequence
的first(where:)
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
在这个虚构的例子中,它的使用可能看起来很愚蠢,但是如果查询非基本元素类型的数组是否存在满足某些条件的任何元素,它非常有用。例如。struct Person {
let age: Int
let name: String
init(_ age: Int, _ name: String) {
self.age = age
self.name = name
}
}
let persons = [Person(17, "Fred"), Person(16, "Susan"),
Person(19, "Hannah"), Person(18, "Sarah"),
Person(23, "Sam"), Person(18, "Jane")]
if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
// ...
} // Hannah can possibly drive the rental car in Sweden.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
// ...
} // Sarah is the same age as Daniel.
任何使用 .filter { ... some condition }.first
的链式操作都可以优化为使用 first(where:)
。后者更能表达意图,并且相比于可能非惰性的应用 .filter
,具有性能优势,因为这些操作将在提取(可能)通过筛选的第一个元素之前传递整个数组。
下面的评论询问:
如何从数组中删除
firstSuchElement
?
与上述用例类似,要删除符合给定谓词的第一个元素。为此,可以使用Collection
的index(where:)
方法(其对于数组集合是可用的)查找满足谓词的第一个元素的索引,然后可以使用该索引与 Array
的 remove(at:)
方法来(可能;如果存在)删除该元素。
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
elements.remove(at: indexOfFirstSuchElement)
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}
或者,如果你想要从数组中删除元素 并处理,可以应用 Optional
:s map(_:)
方法条件地(对于从 index(where:)
返回的 .some(...)
)使用来自 index(where:)
的结果来删除和捕获数组中已移除的元素(在可选绑定子句中)。
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let firstSuchElement = elements.index(where: { $0 == "c" })
.map({ elements.remove(at: $0) }) {
// if we enter here, the first such element have now been
// remove from the array
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// and we may work with it
print(firstSuchElement) // c
}
请注意,在上面的人为示例中,数组成员是简单值类型(String
实例),因此使用谓词查找给定成员有点过度,因为我们可以使用更简单的 index(of :)
方法进行相等性测试,如@DogCoffee's answer所示。但是,如果将上述查找和删除方法应用于Person
示例,则使用带有谓词的index(where:)
是适当的(因为我们不再测试相等性而是测试是否满足提供的谓词)。yourArray.contains(where: {$0.propertyToCheck == value })
返回布尔值。
完成这个最简单的方法是在数组上使用筛选器。
let result = elements.filter { $0==5 }
如果元素存在,result
将包含找到的元素,否则它将为空。因此,仅检查result
是否为空将告诉您该元素是否存在于数组中。我会使用以下内容:
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}
let result = elements.filter { $0==5 }.first
,应该可以达到你想要的效果。 - davetw12first(where: predicate)
。 - Leo DabusSwift 4/5
使用 filter
函数也可以实现这一点。
var elements = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}
从Swift 2.1开始,NSArray有containsObject
方法可以这样使用:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
if find(elements, 5) != nil { }
不够好吗? (备注:该行代码的意思为如果在数组"elements"中找到值为5的元素,则执行大括号内的代码。) - Martin R