0

I have an array defined as:

var MyArrayOfPaintings = [Painting]()

where Painting is defined as:

struct Painting{
    let Artist: String
    let Name: String
    let ThumbNailURL: String
    var PaintsUsed: [Paint]
}

and Paint is defined as:

struct Paint{
    var PaintType: String
    var PaintColorName: String
}

Normally if I want to filter this array based on the Name property within my search bar I would simply add a line as such:

FilteredArray = MyArrayOfPaintings.filter({$0.Name.lowercased().contains(searchText.lowercased())})

This works fine, but now inside my search bar I would also like to be able to search and then filter on MyArray where PaintColorName is the searched value.

How can I filter MyArrayOfPaintings based an a PaintColourName that is provided how do you essentially filter an array based on a array of structs inside it?

2
  • 2
    In the same way. You just need to ask, of each painting, whether any of the paints used has this as its color. Commented Dec 21, 2020 at 0:29
  • 2
    Also please start property names and variable names with a minuscule. Capitals are for types. Commented Dec 21, 2020 at 0:36

1 Answer 1

1

Not related to your question but you can use localizedCaseInsensitiveContains instead of lowercasing name and search text. Regarding your question you can filter the paints that contains the color name.

struct Painting {
    let artist: String
    let name: String
    let thumbNailURL: String
    var paints: [Paint]
}

struct Paint {
    var type: String
    var colorName: String
}

var paintings: [Painting] = [.init(artist: "Artist A", name: "Name A", thumbNailURL: "url1", paints: [.init(type: "a", colorName: "white"), .init(type: "b", colorName: "black")]),
                             .init(artist: "Artist B", name: "Name B", thumbNailURL: "url2", paints: [.init(type: "c", colorName: "red"), .init(type: "d", colorName: "green")])]

let searchText = "green"
let filtered = paintings.filter { $0.paints.contains {$0.colorName.localizedCaseInsensitiveContains(searchText) } }

print(filtered) // [Painting(artist: "Artist B", name: "Name B", thumbNailURL: "url2", paints: [Paint(type: "c", colorName: "red"), Paint(type: "d", colorName: "green")])]

If you would like to get only the paint you can use flatMap instead of filter and then filter instead of contains:

let paints = paintings.flatMap { $0.paints.filter {$0.colorName.localizedCaseInsensitiveContains(searchText) } }

paints  // [{type "d", colorName "green"}]
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you this helped, also did not realise the case insensitive function helps save another line of transforms. Thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.