The natural approach when wanting to construct a subset array from a given array and some predicate is using filter. Since name of the FruitsData struct is an Optional, you'll need to (attempt to) unwrap it prior to comparing it to the non-Optional names in the arrayNames list, e.g. using the map(_:) method of Optional along with optional chaining for handling nil-valued name cases.
E.g.:
// example setup
struct FruitsData {
var name: String?
}
let arrayNames = ["apple", "apricot", "cucumber"]
let secondArray = [
FruitsData(name: "apple"), FruitsData(name: "apricot"),
FruitsData(name: "mango"), FruitsData(name: "grapes"),
FruitsData(name: "tomato"), FruitsData(name: "lichi"),
FruitsData(name: "cucumber"), FruitsData(name: "brinjal")
]
// filter 'secondArray' based on the non-existance of an
// associated fruit name in the 'arrayNames' list
let finalData = secondArray.filter {
$0.name.map { fruitName in !arrayNames.contains(fruitName) } ?? true
}
Since String conforms to Hashable, you might also want to consider letting the list of fruit names to be excluded (arrayNames) be a Set rather than an Array, as the former will allow O(1) lookup when applying contains { ... } to it. E.g.:
let removeNames = Set(arrayNames)
let finalData = secondArray.filter {
$0.name.map { fruitName in !removeNames.contains(fruitName) } ?? true
} /* ^^^^^^^^- O(1) lookup */
If you'd also like to filter out FruitsData instances in secondArray that have nil valued name properties, you can simply with the ... ?? true predicate part above to ... ?? false: the filter operation will then filter out all FruitsData instances whose name property is either nil or present in arrayNames.
// ... filter out also FruitsData instances with 'nil' valued 'name'
let removeNames = Set(arrayNames)
let finalData = secondArray.filter {
$0.name.map { fruitName in !removeNames.contains(fruitName) } ?? false
}