测试定义为 Any 的值的数组包含,但保证属于同一类型。
Testing array containment for values defined as Any, but guaranteed to be of the same type.
基于 (和已接受的答案),我想测试数组中值的包含度。
值存储在定义为 Any
类型的变量中,数组定义为 [Any]
。
变量中存储的值和数组中元素的实际类型在运行时决定,但保证满足以下条件:
- 两种类型(变量和数组元素)一致,并且
- 它们是
String
、Int
或 Bool
之一。
到目前为止,我使这段代码正常工作:
var isContained = false
if let intValue = anyValue as? Int {
isContained = arrayOfAny.contains({element in return ((element as? Int) == intValue)})
}
else if let stringValue = anyValue as? String {
isContained = arrayOfAny.contains({element in return ((element as? String) == stringValue)})
}
else if let boolValue = anyValue as? Bool {
isContained = arrayOfAny.contains({element in return ((element as? Bool) == boolValue)})
}
然而,有很多逻辑重复,我希望我能让它更聪明,也许是这样的:
isContained = arrayOfAny.contains({element in
return ((element as? Equatable) == (anyValue as? Equatable))
})
...但是协议 Equatable
的使用限制阻碍了这一点。有什么建议吗?
我现在明白你在做什么了。这是一个如何让它工作的例子
let arrayOfAny:[AnyObject] = [1,7,9,true, "string"]
func getAny(value:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({[=10=] === value})
}
上述函数将 return 一组匹配项,理想情况下应该是单个结果或空数组。
示例:
self.getAny(1) // [1]
self.getAny(0) // []
您也可以将其修改为简单的 return a Bool
func getAny(value:AnyObject) -> Bool{
return self.arrayOfAny.filter ({[=12=] === value}).count > 0
}
示例:
self.getAny(1) // true
self.getAny(0) // false
编辑:
正如 Martin R 提到的那样,这并不总是有效。不幸的是,在我 post 这个答案之前我没有完全测试它。玩了一会儿之后,我想出了与 NicolasMiari 非常相似的方法:
let arrayOfAny:[AnyObject] = [1,Int.max,9,true, "string"]
func getAny(anyValue:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({
var exist:Bool
switch anyValue.self{
case is String: exist = [=14=] as? String == anyValue as? String
break
case is Int: exist = [=14=] as? Int == anyValue as? Int
break
case is Bool: exist = [=14=] as? Bool == anyValue as? Bool
break
default: exist = false
}
return exist
})
}
这种方法的缺点是 int 1
和 true
将在调用 self.getAny(1)
时被 return 编辑,结果将是 [1,1]
作为 1
和 true
可以成功转换为 Int
和 Bool
,而不是仅仅 return [1]
。
换句话说,如果你的数组中只有 true
而没有 Int 1
你仍然会得到肯定的结果,就好像它存在于你的数组中一样。反之亦然。
基于
值存储在定义为 Any
类型的变量中,数组定义为 [Any]
。
变量中存储的值和数组中元素的实际类型在运行时决定,但保证满足以下条件:
- 两种类型(变量和数组元素)一致,并且
- 它们是
String
、Int
或Bool
之一。
到目前为止,我使这段代码正常工作:
var isContained = false
if let intValue = anyValue as? Int {
isContained = arrayOfAny.contains({element in return ((element as? Int) == intValue)})
}
else if let stringValue = anyValue as? String {
isContained = arrayOfAny.contains({element in return ((element as? String) == stringValue)})
}
else if let boolValue = anyValue as? Bool {
isContained = arrayOfAny.contains({element in return ((element as? Bool) == boolValue)})
}
然而,有很多逻辑重复,我希望我能让它更聪明,也许是这样的:
isContained = arrayOfAny.contains({element in
return ((element as? Equatable) == (anyValue as? Equatable))
})
...但是协议 Equatable
的使用限制阻碍了这一点。有什么建议吗?
我现在明白你在做什么了。这是一个如何让它工作的例子
let arrayOfAny:[AnyObject] = [1,7,9,true, "string"]
func getAny(value:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({[=10=] === value})
}
上述函数将 return 一组匹配项,理想情况下应该是单个结果或空数组。
示例:
self.getAny(1) // [1]
self.getAny(0) // []
您也可以将其修改为简单的 return a Bool
func getAny(value:AnyObject) -> Bool{
return self.arrayOfAny.filter ({[=12=] === value}).count > 0
}
示例:
self.getAny(1) // true
self.getAny(0) // false
编辑:
正如 Martin R 提到的那样,这并不总是有效。不幸的是,在我 post 这个答案之前我没有完全测试它。玩了一会儿之后,我想出了与 NicolasMiari 非常相似的方法:
let arrayOfAny:[AnyObject] = [1,Int.max,9,true, "string"]
func getAny(anyValue:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({
var exist:Bool
switch anyValue.self{
case is String: exist = [=14=] as? String == anyValue as? String
break
case is Int: exist = [=14=] as? Int == anyValue as? Int
break
case is Bool: exist = [=14=] as? Bool == anyValue as? Bool
break
default: exist = false
}
return exist
})
}
这种方法的缺点是 int 1
和 true
将在调用 self.getAny(1)
时被 return 编辑,结果将是 [1,1]
作为 1
和 true
可以成功转换为 Int
和 Bool
,而不是仅仅 return [1]
。
换句话说,如果你的数组中只有 true
而没有 Int 1
你仍然会得到肯定的结果,就好像它存在于你的数组中一样。反之亦然。