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

在Swift中,我如何检查数组中是否存在一个元素?Xcode没有任何关于containinclude,或has的建议,快速搜索这本书什么也没有。知道怎么检查这个吗?我知道有一个方法find返回索引号,但是否有一个方法返回一个布尔像ruby的#include??

我需要的例子:

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

我用滤镜。

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 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的历史答案:

使用这个扩展:(更新到斯威夫特5.2)

 extension Array {
func contains<T>(obj: T) -> Bool where T: Equatable {
return !self.filter({$0 as? T == obj}).isEmpty
}
}

使用:

array.contains(1)

Swift 2、3、4、5:

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

contains()SequenceType协议扩展法(对于Equatable元素的序列),而不是一个全局方法 早些时候发布。< / p >

# EYZ0

# EYZ0

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

为了防止有人试图发现indexPath是否在被选中的函数中(比如在UICollectionViewUITableView cellForItemAtIndexPath函数中):

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

对于那些来这里寻找从数组中查找并移除对象的人:

斯威夫特1

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

斯威夫特2

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

Swift 3,4

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

斯威夫特5.2

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

这是我的小扩展,我刚刚写检查我的委托数组是否包含委托对象(斯威夫特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 result = elements.filter { $0==5 }

如果元素存在,result将有找到的元素,如果元素不存在,则为空。因此,只需检查result是否为空就可以告诉您该元素是否存在于数组中。我会使用以下方法:

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

如果您正在检查自定义类或结构的实例是否包含在数组中,则需要在使用.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)

提示: ==重写应该在全局级别,而不是在你的类/结构中

在Swift 2.1中,nsarray有# eyz0,可以这样使用:

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

如果用户发现特定的数组元素,则使用以下代码相同的整数值。

var arrelemnts = ["sachin", "test", "test1", "test3"]


if arrelemnts.contains("test"){
print("found")   }else{
print("not found")   }

斯威夫特

如果你不使用object,那么你可以使用此代码用于contains。

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


}

(3)迅速

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

如果意图是:

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

然后,作为Sequence蓝图的contains(_:)的替代方案是Sequencefirst(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 ?

与上面类似的用例是删除,它是满足给定谓词的第一个元素。为此,可以使用Collectionindex(where:)方法(可用于数组收集)来查找第一个实现谓词的元素的索引,然后可以使用Arrayremove(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(_:)方法有条件地(对于.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的回答中所示的更简单的index(of:)方法来测试是否相等。但是,如果对Person示例应用上面的查找-删除方法,则使用带谓词的index(where:)是合适的(因为我们不再测试是否相等,而是测试是否满足所提供的谓词)。

斯威夫特4/5

实现这一点的另一种方法是使用过滤器函数

var elements = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}

像这样使用哈希表如何?

首先,创建一个“哈希映射”泛型函数,扩展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
< p > # EYZ0 < br > 通过下面的函数,可以很容易地验证实例是否是数组。< / p >
func verifyIsObjectOfAnArray<T>(_ object: T) -> Bool {
if let _ = object as? [T] {
return true
}


return false
}

甚至你也可以像下面这样访问它。如果对象不是数组,您将收到nil

func verifyIsObjectOfAnArray<T>(_ object: T) -> [T]? {
if let array = object as? [T] {
return array
}


return nil
}

数组

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

包含等于的属性的数组

yourArray.contains(where: {$0.propertyToCheck == value })

返回布尔值。

你可以为Array添加一个扩展:

extension Array {
func contains<T>(_ object: T) -> Bool where T: Equatable {
!self.filter {$0 as? T == object }.isEmpty
}
}

这可以用于:

if myArray.contains(myItem) {
// code here
}