Kent Kent - 17 days ago 5
Swift Question

Get one object in a set of objects by property name in Swift

I have an NSSet which holds a bunch of Detail objects in it. Each Detail object has .name and .text properties. I would like to find one particular Detail in the set where .name = "memo" and see what's being held in its .text property.

How on earth do I do this?

(.indexOf won't work. I don't now if I need to use find and .map somehow, or if there's a means of direct accessing that one particular object in Swift.)

For clarity, I'm using Core Data and each of my "Event" objects has a relationship to many Detail objects. The NSSet of Details is the set that I'm getting off a given Event.

Again, here's what it looks like:


Detail object has properties

.name

.text


I get the details from the active "event" like this:

var someDetails: NSSet()?
someDetails = event.details!


So now I have the set of details for that event.

Now I want to access the detail object whose .name = "memo" and see what it's .text property is.

Creating the details themselves was much easier as all I had to do was create the detail managed object, assign its properties, and add it to a set. When the set had all the objects I needed, I just assigned it to the event.details and saved back to Core Data. I never dreamed it would be much harder to access an individual "detail".

I have no idea what to do next for direct access.

Am I stuck looping through the set, looking at each object, and pulling out the one I want?

Thanks!

Answer

You should use Set instead of NSSet, however I will answer you question about NSSet.

I imagine you have a class like this

class Detail: NSObject {
    let name: String
    let text: String

    init(name: String, text: String) {
        self.name = name
        self.text = text
    }
}

and an NSSet like this

let details = NSSet(array: [
    Detail(name: "a", text: "1"),
    Detail(name: "b", text: "2"),
    Detail(name: "c", text: "3"),
    Detail(name: "d", text: "4")]
    )

now you want all the elms where name is "a", then write

let results =  details.flatMap { $0 as? Detail }.filter { $0.name == "a" }

and finally print them

for result in results {
    print(result.text)
}