如何检查一个元素是否在一个数组中
在Swift中,如何检查数组中是否存在元素? Xcode对于contain
, include
或者没有任何建议,并且通过本书的快速搜索没有任何结果。 任何想法如何检查这个? 我知道有一个方法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)
检查数组中是否存在元素(满足一些条件), 如果是,则继续处理第一个这样的元素
如果意图是:
- 要检查数组中是否存在元素(/满足一些布尔条件,不一定是相等性测试),
- 如果是的话,继续和第一个这样的元素,
然后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
是否在选定的(如在UICollectionView
或UITableView
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") }