2016-11-29 2 views
25

В моем приложении я использовал tableview. Я добавил один объект в массив, когда выбираю ячейку и снимаю выделение и удаляю объект при повторном выборе ячейки. Я использовал этот код, но дал мне ошибку. Пожалуйста, помогите мнеУдаление объекта из массива в swift 3

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    { 
     let cell = tableView.cellForRow(at: indexPath as IndexPath) as? ConctactsCell 
     cell?.imgCheckMark.image = UIImage(named:"check_mark") 
     arrContacts.append(contacts[indexPath.row]) 
     NSLog("selected code = %@",arrContacts); 
    } 
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { 
     let cell = tableView.cellForRow(at: indexPath as IndexPath) as? ConctactsCell 
     cell?.imgCheckMark.image = UIImage(named:"") 
     arrContacts.removeObject(contacts[indexPath.row]) 
     } 

    extension Array { 
     func indexOfObject(object : AnyObject) -> NSInteger { 
      return (self as NSArray).indexOfObject(object) 
     } 

     mutating func removeObject(object : AnyObject) { 
      for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) { 
       self.removeAtIndex(index) 
      } 
     } 
    } 

Это дает мне 3 ошибки, как, что

Declaration is only valid at file scope 
C-style for statement has been removed in Swift 3 
Value of type '[Any]' has no member 'removeObject' 
+0

Обеспечить немного больше кода, показывающий, как вы объявили ваш массив контактов и где вы объявили его –

+1

поместить код декларации о контактах массива –

+0

Вы можете использовать '' Set , а не массив. Можете ли вы предоставить дополнительную информацию о своем контактном объекте? Если вы сделали это сами, вам нужно будет соответствовать «Hashable» и «Equatable», чтобы поместить его в набор – Paulw11

ответ

41

Свифта (3) эквивалентно NSMutableArray «s removeObject является

var array = ["alpha", "beta", "gamma"] 

if let index = array.index(of:"beta") { 
    array.remove(at: index) 
} 

Там нет никакой необходимости, чтобы бросить в NSArray и использовать indexOfObject:

+11

Это лучший ответ, но не глупо не удалять (объект: «бета»). – zeeple

+2

Я думаю, что '.index (из:' доступно только в том случае, если коллекция содержит типы «Equatable». –

+0

@AdamWaite Да, но это относится и к типам Foundation. – vadian

1

Попробуйте это Swift 3

array.remove(at: Index) 

Вместо

array.removeAtIndex(index) 

Update

"Declaration is only valid at file scope". 

Убедитесь, что объект находится в зоне действия. Вы можете указать объем «внутренний», который по умолчанию.

index(of:<Object>) работать, класс должен соответствовать Equatable

3
  1. Декларация расширения должна быть вне класса, переместить его

  2. for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) для цикла в C-стиле и был удален

  3. Измените свой код, чтобы что-то вроде этого, чтобы удалить все подобный объект, если он уже петельные:

    let indexes = arrContacts.enumerated().filter { $0.element == contacts[indexPath.row] }.map{ $0.offset } 
    for index in indexes.reversed() { 
        arrContacts.remove(at: index) 
    } 
    
+0

перечислил -> фильтр -> карта и удалить (at) умный решение. Рекомендовать это –

0

Это как удалить объект из массива:

var array = ["1", "2", "3"] 
array.remove(at: 1) // removes the number 2 

Вы используете «контакты [indexPath.row]» в качестве индекса, возможно, это нужно преобразовать в число? «arrContacts» может быть словарем?

1

правильные и рабочий раствор в одну строки для удаления уникального объекта (названный «objectToRemove») из массива этих объектов (названный «массив») в Swift 3 является:

if let index = array.enumerated().filter({ $0.element === objectToRemove }).map({ $0.offset }).first { 
    array.remove(at: index) 
} 
3

Еще одна приятных и полезное решение заключается в создании такого рода расширения:

extension Array where Element: Equatable { 

    @discardableResult mutating func remove(object: Element) -> Bool { 
     if let index = index(of: object) { 
      self.remove(at: index) 
      return true 
     } 
     return false 
    } 

    @discardableResult mutating func remove(where predicate: (Array.Iterator.Element) -> Bool) -> Bool { 
     if let index = self.index(where: { (element) -> Bool in 
      return predicate(element) 
     }) { 
      self.remove(at: index) 
      return true 
     } 
     return false 
    } 

} 

Таким образом, если у вас есть массив с пользовательскими объектами:

let obj1 = MyObject(id: 1) 
let obj2 = MyObject(id: 2) 
var array: [MyObject] = [obj1, obj2] 

array.remove(where: { (obj) -> Bool in 
    return obj.id == 1 
}) 
// OR 
array.remove(object: obj2) 
36
var a = ["one", "two", "three", "four", "five"] 

// Remove/filter item with value 'three' 
a = a.filter { $0 != "three" } 
+4

Это правильное решение Swift, использующее синтаксические лакомства, предлагаемые языком. – Michael

13

Для Swift 3 вы можете использовать индекс (где :) и включать замыкание, которое сравнивает объект в массиве ($ 0) с тем, что вы ищете.

var array = ["alpha", "beta", "gamma"] 
if let index = array.index(where: {$0 == "beta"}) { 
    array.remove(at: index) 
} 
+0

будет работать, если я хочу удалить несколько объектов? like (where: {$ 0 == "beta" || $ 0 == "gamma"}) –

Смежные вопросы