我如何做 indexOfObject 或适当的 containsObject [英] How do I do indexOfObject or a proper containsObject
问题描述
使用数组:如何做 indexOfObject
或适当的 containsObject
?
With an array: How do I do indexOfObject
or a proper containsObject
?
我的意思是我知道我可以将 Array 桥接到 NSArray
并在那里完成 ^^
但必须有一种原生"的方式来做到这一点
I mean I know I could just bridge the Array to NSArray
and do it there ^^
But there must be a 'native' way of doing this
附言对于 containsObject
我想我也可以过滤数组但是对于 indexOf?
P.S. for the containsObject
I guess I could filter the array too but for indexOf?
推荐答案
您可以使用内置的 find
,从而避免桥接到 Objective-C — 但前提是您的元素类型是 Equatable.(如果它不是 Equatable,您可以使用比较函数和扩展来实现.)
You can use the built-in find
, and thus avoid bridging to Objective-C — but only if your element type is Equatable. (If it isn't Equatable, you can make it so with a comparison function and an extension.)
示例:
func == (lhs:Piece,rhs:Piece) -> Bool {
return lhs.val == rhs.val
}
class Piece:Equatable,Printable {
var val : Int
var description : String { return String(val) }
init (_ v:Int) {
val = v
}
}
现在你可以调用 find(arr,p)
其中 arr
是一个 Array
和 p
> 是一个 Piece
.
Now you can call find(arr,p)
where arr
is an Array<Piece>
and p
is a Piece
.
一旦你有了它,你就可以基于它开发实用程序.例如,这里有一个全局函数,用于从数组中删除一个对象,而无需桥接到 Objective-C:
Once you have this, you can develop utilities based on it. For example, here's a global function to remove an object from an array without bridging to Objective-C:
func removeObject<T:Equatable>(inout arr:Array<T>, object:T) -> T? {
if let found = find(arr,object) {
return arr.removeAtIndex(found)
}
return nil
}
然后像这样测试:
var arr = [Piece(1), Piece(2), Piece(3)]
removeObject(&arr,Piece(2))
println(arr)
<小时>
您也可以对 NSObject 子类执行此操作.示例:
You can do this for NSObject subclasses too. Example:
func == (v1:UIView, v2:UIView) -> Bool {
return v1.isEqual(v2)
}
extension UIView : Equatable {}
现在您可以在 UIView 数组上调用 find
.但是,这有点麻烦,必须为每个您希望能够在该类的 Array 上使用 find
的类执行此操作.我已经向 Apple 提交了一份增强请求,要求将所有 NSObject 子类都视为 Equatable,并且 ==
应该依靠 isEqual:
自动.
Now you can call find
on an Array of UIView. It's sort of a pain in the butt, though, having to do this for every single class where you want to be able to use find
on an Array of that class. I have filed an enhancement request with Apple requesting that all NSObject subclasses be considered Equatable and that ==
should fall back on isEqual:
automatically.
编辑 从 Seed 3 开始,对于 UIView 和其他 NSObject 类是自动的.所以 find
现在只对他们有用.
EDIT Starting in Seed 3, this is automatic for UIView and other NSObject classes. So find
now just works for them.
EDIT 2 从 Swift 2.0 开始,indexOf
将作为方法存在:
EDIT 2 Starting in Swift 2.0, indexOf
will exist as a method:
let s = ["Manny", "Moe", "Jack"]
let ix = s.indexOf("Moe") // 1
或者,它需要一个返回 Bool 的函数:
Alternatively, it takes a function that returns Bool:
let ix2 = s.indexOf {$0.hasPrefix("J")} // 2
同样,这仅适用于 Equatable 的集合,因为显然你无法在大海捞针中找到针,除非你有办法识别针.
Again, this works only on collections of Equatable, since obviously you cannot locate a needle in a haystack unless you have a way of identifying a needle when you come to it.
EDIT 3 Swift 2.0 还引入了协议扩展.这意味着我可以将我的全局函数 removeObject
重写为一个方法!
EDIT 3 Swift 2.0 also introduces protocol extensions. This means I can rewrite my global function removeObject
as a method!
例如:
extension RangeReplaceableCollectionType where Generator.Element : Equatable {
mutating func removeObject(object:Self.Generator.Element) {
if let found = self.indexOf(object) {
self.removeAtIndex(found)
}
}
}
既然Array采用了RangeReplaceableCollectionType,现在可以这样写代码了:
Since Array adopts RangeReplaceableCollectionType, now I can write code like this:
var arr = [Piece(1), Piece(2), Piece(3)]
arr.removeObject(Piece(2))
哦,快乐的一天!
这篇关于我如何做 indexOfObject 或适当的 containsObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!