Reputation: 266
I'm trying to perform a filter on an array of structs whereby if the element exists return the element, otherwise return the first element in the array. At the moment I have a func
to do this, was wondering if there was a more efficient way. Predicate or Array extension?
For example, if this is my array of structures and method:
struct Person {
let name: String
let age: Int
}
let items = [Person(name: "Fred", age: 12),
Person(name: "Bill", age: 14),
Person(name: "Jane", age: 15),
Person(name: "Mary", age: 12)]
// Find the person based on name, if no match, return first item
func filterOrFirst(with name: String? = "") -> Person?
{
if (items.contains(where: {$0.name == name}))
{
return items.first(where: {$0.name == name})
}
return items.first
}
print(filterOrFirst(with: "Bill")) // prints Bill
print(filterOrFirst()) // prints Fred
Upvotes: 0
Views: 2932
Reputation: 1560
You can do it like
func filterOrFirst(with name: String? = "") -> Person? {
if let item = items.first(where: {$0.name == name}) {
return item
}
return items.first
}
So you need not to traverse complete array two times. You can use ternary operator here. But it increases compilation time.
Upvotes: 2
Reputation: 1822
You can get idea from this:
var arrData:[String] = ["Cat","Dog","Horse","Sheep"]
func respondTheValue(strSearch:String) -> String{
let stringToSearch = strSearch
if let index = arrData.index(of: stringToSearch){ //Check if data is present or not
return arrData[index]
}else{ // Data not present then return first
return arrData.first!
}
}
And use it Like:
let responseStr = respondTheValue(strSearch: "Dog")
print(responseStr) //Case True : Output -- Dog
let responseStr1 = respondTheValue(strSearch: "Fish")
print(responseStr1) //Case False : Output -- Cat
Hope this helps.
Upvotes: 0