Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I remove a struct element from an array of structs based on the id of the element in Swift?

Tags:

ios

swift

nsarray

I have a structure in my Swift app:

open class Cluster : NSObject {

    open var username: String? = ""
    open var id: String? = ""
    open var deleted: Bool? = false

}

and now I'm iterating over this array and I'm adding new elements to it, but only in case those elements are not there yet:

if(!self.array.contains(where: {$0.id==temp.id}))
     {
        self.array.append(temp);
     }

I want to tweak this code so that it not only adds new elements if they're not there, but also removes the ones that - in the meantime - had their flag deleted changed to true.

I started writing this code:

if(!self.array.contains(where: {$0.id==temp.id}))
    {
        self.array.append(temp);
    } else {
        if(temp.deleted == true){
            self.array.remove //how can I remove here this specific element?
    }
}
like image 762
user3766930 Avatar asked Sep 02 '25 09:09

user3766930


2 Answers

To remove a particular element from an array, you are supposed to get index of that element first and then delete as shown below:

if let index:Int = self.array.index(where: {$0.id == temp.id && $0.deleted == true}) {
    self.array.remove(at: index)
}
like image 64
KrishnaCA Avatar answered Sep 04 '25 21:09

KrishnaCA


First, I suggest you fix your class:

  • An optional Bool makes no sense - the object is either deleted or not
  • An optional id doesn't make much sense either; All objects need an id
  • If you implement the hash and equality parts of NSObject then you get access to array's index(of:) method and you can use sets.

Cluster.swift

open class Cluster : NSObject {

    open var username: String? = ""
    open let id: String
    open var isDeleted: Bool = false

    init(id: String) {
        self.id = id
    }

    open override var hashValue: Int {
        get {
            return self.id.hashValue
        }
    }

    open override func isEqual(_ object: Any?) -> Bool {
        guard let rhs = object as? Cluster else {
            return false
        }

        let lhs = self

        return lhs.id == rhs.id
    }  
}

Now, given an array of Cluster objects, you can remove the deleted ones using:

let cleanArray = dirtyArrayOfCluster.filter {
    !$0.isDeleted
}

And you can remove duplicates by passing the array through a set:

let deDupedArray = Array(Set(cleanArray))
like image 27
Paulw11 Avatar answered Sep 04 '25 23:09

Paulw11