在Swift中,如何检查数组中是否存在元素? Xcode对contain
,include
或has
没有任何建议,并且快速搜索该书并未发现任何内容。知道怎么检查这个吗?我知道有一个方法find
可以返回索引号,但是有一个方法可以返回一个类似ruby' s #include?
的布尔值吗?
我需要的例子:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
答案 0 :(得分:774)
斯威夫特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")
}
答案 1 :(得分:115)
对于那些来到这里寻找查找并从数组中删除对象的人:
Swift 1
if let index = find(itemList, item) {
itemList.removeAtIndex(index)
}
Swift 2
if let index = itemList.indexOf(item) {
itemList.removeAtIndex(index)
}
斯威夫特3,4,5
if let index = itemList.index(of: item) {
itemList.remove(at: index)
}
答案 2 :(得分:57)
使用此扩展程序:
extension Array {
func contains<T where T : Equatable>(obj: T) -> Bool {
return self.filter({$0 as? T == obj}).count > 0
}
}
用作:
array.contains(1)
更新了Swift 2/3
请注意,从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
答案 3 :(得分:34)
如果您要检查数组中是否包含自定义类或结构的实例,则需要先实施 Equatable 协议,然后才能使用。含有(myObject的)。
例如:
struct Cup: Equatable {
let filled:Bool
}
static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
return lhs.filled == rhs.filled
}
然后你可以这样做:
cupArray.contains(myCup)
提示:==覆盖应该在全局级别,而不是在您的类/ struct中
答案 4 :(得分:28)
我使用过滤器。
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
Hurray默认实现!
if elements.contains(5) {
// any matching items are in results
} else {
// not found
}
答案 5 :(得分:18)
(Swift 3)
如果意图是:
然后,contains(_:)
替代first(where:)
为蓝色Sequence
,index(where:)
为Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
在这个人为的例子中,它的用法看似愚蠢,但是如果查询非基本元素类型的数组是否存在满足某些条件的任何元素,那么它非常有用。 E.g。
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
的remove(at:)
方法(数组集合中可用)来查找满足谓词的第一个元素的索引,之后索引可以与{一起使用{3}} Array
的方法(可能;鉴于它存在)删除该元素。
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(_:)
方法(for {{ 1}}从.some(...)
返回)使用index(where:)
的结果从数组中删除并捕获已删除的元素(在可选的绑定子句中)。
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
方法,如@DogCoffee's answer所示。但是,如果将上述查找和删除方法应用于index(of:)
示例,则使用带有谓词的Person
是合适的(因为我们不再测试相等性,而是为了完成提供的谓词)。
答案 6 :(得分:13)
实现此目的的最简单方法是在阵列上使用过滤器。
let result = elements.filter { $0==5 }
result
将具有找到的元素(如果存在),如果该元素不存在则将为空。因此,只需检查result
是否为空将告诉您元素是否存在于数组中。我会使用以下内容:
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}
答案 7 :(得分:6)
从Swift 2.1开始,NSArrays的containsObject
可以像这样使用:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
答案 8 :(得分:4)
以防任何人试图查找indexPath
是否属于所选内容(例如UICollectionView
或UITableView
cellForItemAtIndexPath
个功能):
var isSelectedItem = false
if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
if contains(selectedIndexPaths, indexPath) {
isSelectedItem = true
}
}
答案 9 :(得分:4)
包含等于的属性的数组
yourArray.contains(where: {$0.propertyToCheck == value })
返回布尔值。
答案 10 :(得分:3)
这是我刚写的一个小扩展,用于检查我的委托数组是否包含委托对象( Swift 2 )。 :)它也适用于像魅力一样的值类型。
extension Array
{
func containsObject(object: Any) -> Bool
{
if let anObject: AnyObject = object as? AnyObject
{
for obj in self
{
if let anObj: AnyObject = obj as? AnyObject
{
if anObj === anObject { return true }
}
}
}
return false
}
}
如果您知道如何优化此代码,请告诉我们。
答案 11 :(得分:3)
Swift 4,实现这一目标的另一种方式, 使用过滤功能
var elements = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}
答案 12 :(得分:2)
如果用户找到特定的数组元素,则使用下面的代码与整数值相同。
var arrelemnts = ["sachin", "test", "test1", "test3"]
if arrelemnts.contains("test"){
print("found") }else{
print("not found") }
答案 13 :(得分:2)
斯威夫特
如果您没有使用对象,则可以使用此代码进行包含。
let elements = [ 10, 20, 30, 40, 50]
if elements.contains(50) {
print("true")
}
如果你在swift中使用NSObject类。这个变量是根据我的要求。你可以修改你的要求。
var cliectScreenList = [ATModelLeadInfo]()
var cliectScreenSelectedObject: ATModelLeadInfo!
这是针对相同的数据类型。
{ $0.user_id == cliectScreenSelectedObject.user_id }
如果您想要AnyObject类型。
{ "\($0.user_id)" == "\(cliectScreenSelectedObject.user_id)" }
完整条件
if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false {
cliectScreenSelected.append(cliectScreenSelectedObject)
print("Object Added")
} else {
print("Object already exists")
}
答案 14 :(得分:1)
如何使用哈希表来完成这项工作呢?
首先,创建一个&#34;哈希映射&#34;泛型函数,扩展了Sequence协议。
extension Sequence where Element: Hashable {
func hashMap() -> [Element: Int] {
var dict: [Element: Int] = [:]
for (i, value) in self.enumerated() {
dict[value] = i
}
return dict
}
}
只要数组中的项符合Hashable,就像整数或字符串一样,此扩展名将起作用,这是用法......
let numbers = Array(0...50)
let hashMappedNumbers = numbers.hashMap()
let numToDetect = 35
let indexOfnumToDetect = hashMappedNumbers[numToDetect] // returns the index of the item and if all the elements in the array are different, it will work to get the index of the object!
print(indexOfnumToDetect) // prints 35
但是现在,让我们只关注元素是否在数组中。
let numExists = indexOfnumToDetect != nil // if the key does not exist
means the number is not contained in the collection.
print(numExists) // prints true
答案 15 :(得分:0)
Swift 4.2 +
您可以通过以下函数轻松地验证您的实例是否为数组。
Nil
即使您可以按以下方式访问它。如果对象不是数组,您将收到 func verifyIsObjectOfAnArray<T>(_ object: T) -> [T]? {
if let array = object as? [T] {
return array
}
return nil
}
。
library("fitdistrplus")
rain <- Rainfall$Rainfall
rain
fitdistr(rain,"normal")
plotdist(rain)
descdist(rain, discrete = FALSE)
fit.norm <- fitdist(rain, "norm")
plot(fit.norm)
fit.1 <- fitdist(rain, "gamma", method = "mle", lower = c(0,0), start =
list(scale = 1, shape = 1))
plot(fit.1)
答案 16 :(得分:0)
let elements = [1, 2, 3, 4, 5, 5]
elements.contains(5) // true
elements.firstIndex(of: 5) // 4
elements.firstIndex(of: 10) // nil
let results = elements.filter { element in element == 5 }
results.count // 2