Cory Billeaud Cory Billeaud - 20 days ago 26
iOS Question

swift 3 filter array of dictionaries by string value of key in dictionary

I have a class such as this

class FoundItem : NSObject {

var id : String!
var itemName : String!
var itemId : Int!
var foundBy : String!
var timeFound : String!

init(id: String,
itemName: String,
itemId: Int,
foundBy: String,
timeFound: String)

{
self.id = id
self.itemName = itemName
self.itemId = itemId
self.foundBy = foundBy
self.timeFound = timeFound

}


and I reference it on my

class MapViewVC: UIViewController, MKMapViewDelegate {

var found = [FoundItem]()

var filterItemName : String()

}


My foundItems are generated by into a array of dictionaries from my class of FoundItems from a firebase query. I then get a string of that itemName that is generated from an another view controller that is a collection view on the didSelection function. I want to take that string and then filter or search the arrays with the string itemName that is equal from the itemName string from my previous viewController. Then removed the array of dictionaries that are not equal to the itemName. Not just the objects, but the entire array that contains non-equal key, value pair. I have looked for days, and I am stuck on filtering an array of dictionaries created from a class. I have looked and tried NSPredicates, for-in loops, but all that ends up happening is creating a new arrays, or bool that finds my values or keys are equal. Here is the current function I have written.

func filterArrayBySearch() {

if self.filterItemName != nil {

dump(found)

let namePredicate = NSPredicate(format: "itemName like %@", "\(filterItemName)")
let nameFilter = found.filter { namePredicate.evaluate(with: $0) }

var crossRefNames = [String: [FoundItem]]()
for nameItemArr in found {
let listName = nameItem.itemName
let key = listName

if crossRefNames.index(forKey: key!) != nil {

crossRefNames[key!]?.append(nameItemArr)

if !("\(key)" == "\(filterItemName!)") {

print("------------- Success have found [[[[[[ \(key!) ]]]]]] and \(filterItemName!) to be equal!!")

// crossRefNames[key!]?.append(nameItemArr)

} else {

print("!! Could not find if \(key!) and \(filterItemName!) are equal !!")
}


} else {

crossRefNames[key!] = [nameItemArr]
}
}

} else {

print("No Data from Search/FilterVC Controller")
}
}


Can anyone help? It seems like it would be simple task to find the value and then filter out the dictionaries that are not equal to the itemName string, but I keep hitting a wall. And running into for-in loops myself :P trying different things to achieve the same task.

par par
Answer

I hope I understood what you were asking. You mention an "array of dictionaries" but you don't actually have an array of dictionaries anywhere in the code you've posted.

As far as I can tell, you are asking how to find all the entries in the found array for which itemName equals the filterItemName property.

If so, all you should need to do is:

let foundItems = found.filter { $0.itemName == filterItemName }

That's it.


Some other ideas:

If you want to search for items where filterItemName is contained in the itemName, you could do something like this:

let foundItems = found.filter { $0.itemName.contains(filterItemName) }

You could also make use of the lowercased() function if you want to do case-insensitive search.

You could also return properties of your found elements into an array:

let foundIds = found.filter { $0.itemName == filterItemName }.map { $0.itemId }

Comments