filter an object array based on another

Hi, I'm new to SwiftUI and have been trying to accomplish this without success.

I have the following arrays and need to filter out from the options array the items that exist in the selected array.

import SwiftUI

struct Option: Decodable, Hashable {
    var userCode: String
    var optType: String
    var optValue: String
}

struct Selected: Decodable, Hashable {
    var userCode: String
    var tradeCode: String
    var optType: String
    var optValue: String
}

struct ContentView: View {

    @State var options = [
        Option(userCode: "1", optType: "Emotions", optValue: "Sad"),
        Option(userCode: "1", optType: "Emotions", optValue: "Happy"),
        Option(userCode: "1", optType: "Emotions", optValue: "Angry"),
        Option(userCode: "1", optType: "Emotions", optValue: "Calm")
]

    @State var selected = [
        Selected(userCode: "1", tradeCode: "1", optType: "Emotions", optValue: "Sad"),
        Selected(userCode: "1", tradeCode: "1", optType: "Emotions", optValue: "Happy")
    ]

    var body: some View {

        Button("Options Not Selected") {
        //Here I need an array of the options NOT  selected
        }
    }
}

Any help would be greatly appreciated.

Thanks

Answered by OOPer in 693535022

It is not clear enough, but you can prepare some extension like this:

extension Selected {
    func matches(_ option: Option) -> Bool {
        //↓Modify the following expression to fit for your purpose
        return optType == option.optType
            && optValue == option.optValue
    }
}

And then:

        Button("Options Not Selected") {
            let optionsNotSelected = options.filter { option in
                !selected.contains {$0.matches(option)}
            }
            print(optionsNotSelected)
            //Use `optionsNotSelected`...
        }

Option and Selected are different types. How can you judge if an Option exist in the selected Array? Compare userCode? Compare optType? Compare optValue? Or some other way?

Accepted Answer

It is not clear enough, but you can prepare some extension like this:

extension Selected {
    func matches(_ option: Option) -> Bool {
        //↓Modify the following expression to fit for your purpose
        return optType == option.optType
            && optValue == option.optValue
    }
}

And then:

        Button("Options Not Selected") {
            let optionsNotSelected = options.filter { option in
                !selected.contains {$0.matches(option)}
            }
            print(optionsNotSelected)
            //Use `optionsNotSelected`...
        }

I would do something like this:

struct Option: Decodable, Hashable {
    var userCode: String
    var optType: String
    var optValue: String
}

struct Selected: Decodable, Hashable {
    var userCode: String
    var tradeCode: String
    var optType: String
    var optValue: String
}

struct ContentView: View {

    @State var options = [
        Option(userCode: "1", optType: "Emotions", optValue: "Sad"),
        Option(userCode: "1", optType: "Emotions", optValue: "Happy"),
        Option(userCode: "1", optType: "Emotions", optValue: "Angry"),
        Option(userCode: "1", optType: "Emotions", optValue: "Calm")
]

    @State var selected = [
        Selected(userCode: "1", tradeCode: "1", optType: "Emotions", optValue: "Sad"),
        Selected(userCode: "1", tradeCode: "1", optType: "Emotions", optValue: "Happy")
    ]

    var body: some View {

        Button("Options Not Selected") {
            let notSelectedOptions = options.filter() { !isOptionInSelected(for: $0) }
            print(notSelectedOptions)    // Just to check
        // Here I need an array of the options NOT  selected
            
        }
    }
    
    func isOptionInSelected(for option: Option) -> Bool {

        for select in selected {
            if option.userCode == select.userCode && option.optType == select.optType && option.optValue == select.optValue {
                return true
            }
        }
        return false
    }
            
}
filter an object array based on another
 
 
Q