Sno*_*man 140 arrays ios swift
extension Array {
func removeObject<T where T : Equatable>(object: T) {
var index = find(self, object)
self.removeAtIndex(index)
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到了错误 var index = find(self, object)
'T'不能转换为'T'
我也试过这个方法签名:func removeObject(object: AnyObject)但是,我得到了同样的错误:
'AnyObject'不能转换为'T'
这样做的正确方法是什么?
Mar*_*n R 166
从Swift 2开始,这可以通过协议扩展方法实现.
removeObject()被定义为符合RangeReplaceableCollectionType(特别是Array)所有类型的方法,如果集合的元素是Equatable:
extension RangeReplaceableCollectionType where Generator.Element : Equatable {
// Remove first collection element that is equal to the given `object`:
mutating func removeObject(object : Generator.Element) {
if let index = self.indexOf(object) {
self.removeAtIndex(index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
例:
var ar = [1, 2, 3, 2]
ar.removeObject(2)
print(ar) // [1, 3, 2]
Run Code Online (Sandbox Code Playgroud)
更新Swift 2/Xcode 7 beta 2:由于Airspeed Velocity在评论中注意到,现在实际上可以在对模板更具限制性的泛型类型上编写方法,因此该方法现在实际上可以定义为扩展的Array:
extension Array where Element : Equatable {
// ... same method as above ...
}
Run Code Online (Sandbox Code Playgroud)
协议扩展仍然具有适用于更大类型的优点.
Swift 3更新:
extension Array where Element: Equatable {
// Remove first collection element that is equal to the given `object`:
mutating func remove(object: Element) {
if let index = index(of: object) {
remove(at: index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
dre*_*wag 65
您不能在对模板更具限制性的泛型类型上编写方法.
注:如雨燕2.0的,现在就可以编写方法是在模板上更加严格.如果您已将代码升级到2.0,请进一步查看其他答案,以获取使用扩展实现此目的的新选项.
您收到错误的原因'T' is not convertible to 'T'是您实际上在方法中定义了一个与原始T无关的新 T.如果您想在方法中使用T,则可以在方法中指定它.
您得到第二个错误的原因'AnyObject' is not convertible to 'T'是T的所有可能值都不是所有类.对于要转换为AnyObject的实例,它必须是一个类(它不能是struct,enum等).
你最好的办法是使它成为一个接受数组作为参数的函数:
func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {
}
Run Code Online (Sandbox Code Playgroud)
或者,不是修改原始数组,而是通过返回副本使您的方法更安全,可重用:
func arrayRemovingObject<T : Equatable>(object: T, fromArray array: [T]) -> [T] {
}
Run Code Online (Sandbox Code Playgroud)
作为我不推荐的替代方法,如果存储在数组中的类型无法转换为方法模板(即相等),则可以使方法无提示失败.(为清楚起见,我使用U而不是T作为方法的模板):
extension Array {
mutating func removeObject<U: Equatable>(object: U) {
var index: Int?
for (idx, objectToCompare) in enumerate(self) {
if let to = objectToCompare as? U {
if object == to {
index = idx
}
}
}
if(index != nil) {
self.removeAtIndex(index!)
}
}
}
var list = [1,2,3]
list.removeObject(2) // Successfully removes 2 because types matched
list.removeObject("3") // fails silently to remove anything because the types don't match
list // [1, 3]
Run Code Online (Sandbox Code Playgroud)
编辑为了克服沉默失败,你可以将成功作为一个bool返回:
extension Array {
mutating func removeObject<U: Equatable>(object: U) -> Bool {
for (idx, objectToCompare) in self.enumerate() { //in old swift use enumerate(self)
if let to = objectToCompare as? U {
if object == to {
self.removeAtIndex(idx)
return true
}
}
}
return false
}
}
var list = [1,2,3,2]
list.removeObject(2)
list
list.removeObject(2)
list
Run Code Online (Sandbox Code Playgroud)
Ján*_*nos 28
简要而简洁地说:
func removeObject<T : Equatable>(object: T, inout fromArray array: [T])
{
var index = find(array, object)
array.removeAtIndex(index!)
}
Run Code Online (Sandbox Code Playgroud)
ros*_*och 17
阅读以上所有内容后,我认为最好的答案是:
func arrayRemovingObject<U: Equatable>(object: U, # fromArray:[U]) -> [U] {
return fromArray.filter { return $0 != object }
}
Run Code Online (Sandbox Code Playgroud)
样品:
var myArray = ["Dog", "Cat", "Ant", "Fish", "Cat"]
myArray = arrayRemovingObject("Cat", fromArray:myArray )
Run Code Online (Sandbox Code Playgroud)
Swift 2(xcode 7b4)数组扩展:
extension Array where Element: Equatable {
func arrayRemovingObject(object: Element) -> [Element] {
return filter { $0 != object }
}
}
Run Code Online (Sandbox Code Playgroud)
样品:
var myArray = ["Dog", "Cat", "Ant", "Fish", "Cat"]
myArray = myArray.arrayRemovingObject("Cat" )
Run Code Online (Sandbox Code Playgroud)
Swift 3.1更新
现在又回到了Swift 3.1.以下是一个扩展,提供详尽,快速,变异和创建变体.
extension Array where Element:Equatable {
public mutating func remove(_ item:Element ) {
var index = 0
while index < self.count {
if self[index] == item {
self.remove(at: index)
} else {
index += 1
}
}
}
public func array( removing item:Element ) -> [Element] {
var result = self
result.remove( item )
return result
}
}
Run Code Online (Sandbox Code Playgroud)
样品:
// Mutation...
var array1 = ["Cat", "Dog", "Turtle", "Cat", "Fish", "Cat"]
array1.remove("Cat")
print(array1) // ["Dog", "Turtle", "Socks"]
// Creation...
let array2 = ["Cat", "Dog", "Turtle", "Cat", "Fish", "Cat"]
let array3 = array2.array(removing:"Cat")
print(array3) // ["Dog", "Turtle", "Fish"]
Run Code Online (Sandbox Code Playgroud)
Sri*_*ala 13
使用协议扩展,您可以执行此操作,
extension Array where Element: Equatable {
mutating func remove(object: Element) {
if let index = indexOf({ $0 == object }) {
removeAtIndex(index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
类的功能相同,
斯威夫特2
extension Array where Element: AnyObject {
mutating func remove(object: Element) {
if let index = indexOf({ $0 === object }) {
removeAtIndex(index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特3
extension Array where Element: AnyObject {
mutating func remove(object: Element) {
if let index = index(where: { $0 === object }) {
remove(at: index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果一个类实现了Equatable,它就会变得模棱两可,编译器会抛出一个错误.
小智 7
在swift 2.0中使用协议扩展
extension _ArrayType where Generator.Element : Equatable{
mutating func removeObject(object : Self.Generator.Element) {
while let index = self.indexOf(object){
self.removeAtIndex(index)
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
73680 次 |
| 最近记录: |