このようなクラスがあります
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
}
そして私はそれを
class MapViewVC: UIViewController, MKMapViewDelegate {
var found = [FoundItem]()
var filterItemName : String()
}
FoundItem
は、firebaseクエリからのFoundItem
のクラスから辞書の配列に生成されます。次に、itemName
関数のコレクションビューである別のView Controllerから生成されたdidSelection
の文字列を取得します。その文字列を取得してから、以前のitemName
のitemName
文字列と等しい文字列viewController
で配列をフィルターまたは検索します。次に、itemName
と等しくない辞書の配列を削除しました。オブジェクトだけでなく、等しくないキーと値のペアを含む配列全体。私は何日も探していましたが、クラスから作成された辞書の配列のフィルタリングに固執しています。 NSPredicatesのfor-inループを調べてみましたが、最終的に起こるのは、値またはキーが等しいことを検出する新しい配列またはブールを作成することだけです。これが私が書いた現在の関数です。
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")
}
}
誰でも助けることができますか?値を見つけてitemName
文字列に等しくない辞書をフィルターで除外するのは簡単なタスクのようですが、壁にぶつかり続けます。そして、自分自身でfor-inループに遭遇すると、同じタスクを達成するためにさまざまなことを試みます。
あなたが何を求めているのか理解できたと思います。 「辞書の配列」に言及していますが、実際に投稿したコードのどこにも辞書の配列はありません。
私の知る限り、found
がitemName
プロパティに等しいfilterItemName
配列内のすべてのエントリを見つける方法を尋ねています。
もしそうなら、あなたがする必要があるすべては次のとおりです。
_let foundItems = found.filter { $0.itemName == filterItemName }
_
それでおしまい。
他のいくつかのアイデア:
filterItemName
がitemName
に含まれるアイテムを検索する場合は、次のようにします。
let foundItems = found.filter { $0.itemName.contains(filterItemName) }
大文字と小文字を区別しない検索を行う場合は、lowercased()
関数を使用することもできます。
見つかった要素のプロパティを配列に返すこともできます。
_let foundIds = found.filter { $0.itemName == filterItemName }.map { $0.itemId }
_
次の方法を使用して辞書の配列をソートします
var dict:[[String:AnyObject]] = sortedArray.filter{($0["parentId"] as! String) == "compareId"}
filter関数は、コレクション内のすべてのアイテムをループし、包含条件を満たすアイテムのみを含むコレクションを返します。
この辞書の配列から単一のオブジェクトを取得できます。次のコードを使用できます
var dict = sortedArray.filter{($0["parentId"] as! String) == "compareId"}.first
OR
let dict = sortedArray.filter{ ($0["parentId"] as! String) == "compareId" }.first
ここではCoreDataを使用し、Array of Dictionaryを持っています。ここでは、値がinvoice配列であるキーpaymentToInvoiceをフィルターし、キーにピープルディクショナリーを含むキーinvoiceToPeopleをフィルターし、FirstName、lastName、searchTextを含む組織の複数キーを検索します。これがお役に立てば幸いです
var searchDict = dict.filter { (arg0) -> Bool in
let (key, value) = arg0
for paymentInfo in (value as! [PaymentInfo]){
let organization = (Array((value as! [PaymentInfo])[0].paymentToInvoice!)[0] as! InvoiceInfo).invoiceToPeople?.organization
let firstName = (Array((value as! [PaymentInfo])[0].paymentToInvoice!)[0] as! InvoiceInfo).invoiceToPeople?.firstName
let lastName = (Array((value as! [PaymentInfo])[0].paymentToInvoice!)[0] as! InvoiceInfo).invoiceToPeople?.lastName
return organization?.localizedStandardRange(of: searchText) != nil || firstName?.localizedStandardRange(of: searchText) != nil || lastName?.localizedStandardRange(of: searchText) != nil
}
return true
}
このコードがSwift3とSwift4,4.1の両方に使用するキー名を持つ辞書オブジェクトの配列の述語を使用するローカル検索フィルター。
func updateSearchResults(for searchController:
UISearchController) {
if (searchController.searchBar.text?.characters.count)! > 0 {
guard let searchText = searchController.searchBar.text,
searchText != "" else {
return
}
usersDataFromResponse.removeAll()
let searchPredicate = NSPredicate(format: "userName
CONTAINS[C] %@", searchText)
usersDataFromResponse = (filteredArray as
NSArray).filtered(using: searchPredicate)
print ("array = \(usersDataFromResponse)")
self.listTableView.reloadData()
}
}