web-dev-qa-db-ja.com

swift 3辞書のキーの文字列値による辞書のフィルター配列

このようなクラスがあります

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の文字列を取得します。その文字列を取得してから、以前のitemNameitemName文字列と等しい文字列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ループに遭遇すると、同じタスクを達成するためにさまざまなことを試みます。

6
Cory Billeaud

あなたが何を求めているのか理解できたと思います。 「辞書の配列」に言及していますが、実際に投稿したコードのどこにも辞書の配列はありません。

私の知る限り、founditemNameプロパティに等しいfilterItemName配列内のすべてのエントリを見つける方法を尋ねています。

もしそうなら、あなたがする必要があるすべては次のとおりです。

_let foundItems = found.filter { $0.itemName == filterItemName }_

それでおしまい。


他のいくつかのアイデア:

filterItemNameitemNameに含まれるアイテムを検索する場合は、次のようにします。

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

大文字と小文字を区別しない検索を行う場合は、lowercased()関数を使用することもできます。

見つかった要素のプロパティを配列に返すこともできます。

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

17
par

次の方法を使用して辞書の配列をソートします

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
4
IKKA

ここでは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
  }
0
Yogesh Patel

このコードが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()
    }


  }