pentool
pentool

Reputation: 565

Check if a value of an array of dictionaries matches a list of array elements

I have an array (items) and an array of dictionaries (data) in Swift:

let items = [2, 6, 4]

var data = [
    ["id": "1", "title": "Leslie", "color": "brown"],
    ["id": "8", "title": "Mary", "color": "red"],
    ["id": "6", "title": "Joe", "color": "blue"],
    ["id": "2", "title": "Paul", "color": "gray"],
    ["id": "5", "title": "Stephanie", "color": "pink"],
    ["id": "9", "title": "Steve", "color": "purple"],
    ["id": "3", "title": "Doug", "color": "violet"],
    ["id": "4", "title": "Ken", "color": "white"],
    ["id": "7", "title": "Annie", "color": "black"]
]

I'd like to create an array that contains those arrays of dictionaries whose "id" equals to the numbers provided in the 'items' array. Aka I'd like to end up with having an array of:

var result = [
    ["id": "6", "title": "Joe", "color": "blue"],
    ["id": "2", "title": "Paul", "color": "gray"],
    ["id": "4", "title": "Ken", "color": "white"]
]

I was trying to use predicates, but after a severe headache and a cardiac arrest I didn't get nowhere with them. They seem insanely complex for this task. I'm now at a point where I just want to do this in a simple for-in loop.

Is there a clever way to do this using predicates or something else?

Upvotes: 1

Views: 3647

Answers (3)

pentool
pentool

Reputation: 565

Thanks everyone for the reply! I think Eric D's solution comes closest to what I was after.

I was finally be able to find the solution with good description on raywenderlich.com: https://www.raywenderlich.com/82599/swift-functional-programming-tutorial

Using that method (again, very close to what Eric D has suggested), first I can break it down as:

func findItems(value: [String: String]) -> Bool {
    return items.contains(Int(value["id"]!)!)
}
var result = data.filter(findItems)

I can further reduce that to:

var result = data.filter {
    (value) in items.contains(Int(value["id"]!)!)
}

Which, again, can be reduced to a single line, as in:

var result = data.filter { items.contains(Int($0["id"]!)!) }

Thanks again to everyone!

Upvotes: 0

Twitter khuong291
Twitter khuong291

Reputation: 11672

Try this, should work:

let items = [2, 6, 4]
var data = [
    ["id": "1", "title": "Leslie", "color": "brown"],
    ["id": "8", "title": "Mary", "color": "red"],
    ["id": "6", "title": "Joe", "color": "blue"],
    ["id": "2", "title": "Paul", "color": "gray"],
    ["id": "5", "title": "Stephanie", "color": "pink"],
    ["id": "9", "title": "Steve", "color": "purple"],
    ["id": "3", "title": "Doug", "color": "violet"],
    ["id": "4", "title": "Ken", "color": "white"],
    ["id": "7", "title": "Annie", "color": "black"]
]

var result = [Dictionary<String, String>]()

for index in 0..<data.count {
    let myData = data[index]
    let dataID = data[index]["id"]
    for i in 0..<items.count {
        if dataID == "\(items[i])" {
            result.append(myData)
        }
    }
}

for i in 0..<result.count {
    print(result[i])
}

Result is:

enter image description here

Upvotes: 0

Eric Aya
Eric Aya

Reputation: 70098

Use filter and contains like this:

let result = data.filter { dict in
    if let idString = dict["id"], id = Int(idString) {
        return items.contains(id)
    }
    return false
}

Upvotes: 6

Related Questions