如何检查一个元素是否在一个数组中

在Swift中,如何检查数组中是否存在元素? Xcode对于containinclude或者没有任何建议,并且通过本书的快速搜索没有任何结果。 任何想法如何检查这个? 我知道有一个方法find ,返回索引号,但有没有一种方法,返回一个布尔像红宝石的#include?

我需要的例子:

 var elements = [1,2,3,4,5] if elements.contains(5) { //do something } 

斯威夫特2,3,4:

 let elements = [1, 2, 3, 4, 5] if elements.contains(5) { print("yes") } 

contains()SequenceType (对于Equatable元素的SequenceType contains()协议扩展方法 ,而不是像早期版本中的全局方法。

备注:

  • contains()方法要求序列元素采用Equatable协议,比较安德鲁斯的答案 。
  • 如果序列元素是NSObject子类的实例,则必须重写isEqual: :,请参阅Swift中的NSObject子类:hash vs hashValue,isEqual vs == 。
  • 还有一个 – more general – contains()方法,它不要求元素是可以等同的,并且把一个谓词作为一个参数,比如见速记测试一个数组是否存在于Swift中? 。

Swift旧版本:

 let elements = [1,2,3,4,5] if contains(elements, 5) { println("yes") } 

对于那些来这里寻找一个查找和从数组中删除一个对象:

斯威夫特1

 if let index = find(itemList, item) { itemList.removeAtIndex(index) } 

Swift 2

 if let index = itemList.indexOf(item) { itemList.removeAtIndex(index) } 

斯威夫特3,4

 if let index = itemList.index(of: item) { itemList.remove(at: index) } 

使用这个扩展名:

 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 

如果您正在检查数组中是否包含自定义类或结构的实例,则在使用.contains(myObject)之前,您需要实现Equatable协议。

例如:

 struct 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)

检查数组中是否存在元素(满足一些条件), 如果是,则继续处理第一个这样的元素

如果意图是:

  1. 要检查数组中是否存在元素(/满足一些布尔条件,不一定是相等性测试),
  2. 如果是的话,继续和第一个这样的元素,

然后contains(_:)作为蓝图Sequence的替代方法是first(where:) Sequence

 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:)取代。 后者显示出更好的意图,并且具有超过可能的非过滤器的过滤器的性能优势,因为在提取通过过滤器的(可能的)第一元素之前,它们将通过全阵列。


检查数组中是否存在元素(满足某些条件), 如果是,则删除第一个这样的元素

下面的评论查询:

我怎样才能从数组中删除firstSuchElement

上面类似的用例是删除满足给定谓词的第一个元素。 为此,可以使用Collection (对于数组集合)可用的index(where:)方法来查找满足谓词的第一个元素的索引,之后索引可以与remove(at:) 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(_:)方法来有条件地(对于.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实例),所以使用谓词来查找给定的成员有点过分杀死,因为我们可能简单地使用更简单的index(of:)方法如@ DogCoffee的答案所示 。 如果将上面的查找和删除方法应用到Person示例,则使用index(where:)和predicate是合适的(因为我们不再测试相等性,但是为了实现提供的谓词)。

最简单的方法是在数组上使用过滤器。

 let result = elements.filter { $0==5 } 

如果存在, result将具有找到的元素,如果元素不存在,则result将为空。 所以简单地检查result是否为空将告诉你该元素是否存在于数组中。 我会使用以下内容:

 if result.isEmpty { // element does not exist in array } else { // element exists } 

从Swift 2.1开始,NSArrays拥有可以像这样使用的containsObject

 if myArray.containsObject(objectImCheckingFor){ //myArray has the objectImCheckingFor } 

以防万一有人试图找到一个indexPath是否在选定的(如在UICollectionViewUITableView cellForItemAtIndexPath函数):

  var isSelectedItem = false if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{ if contains(selectedIndexPaths, indexPath) { isSelectedItem = true } } 

这里是我写的小扩展,以检查我的委托数组是否包含委托对象( 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 } } 

如果你有一个想法如何优化这个代码,比只是让我知道。

迅速

如果你不使用对象,那么你可以使用这个代码包含。

 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") } 

如果用户找到特定的数组元素,那么使用下面的代码相同的整数值。

 var arrelemnts = ["sachin", "test", "test1", "test3"] if arrelemnts.contains("test"){ print("found") }else{ print("not found") }