Swift 3:通过字典中键的字符串值过滤字典数组

12

我有一个类似这样的类

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查询中获得的一个字典数组生成。我从另一个视图控制器(集合视图)中获取一个itemName字符串,然后筛选或搜索包含与前一个viewController中的itemName相等的itemName字符串的数组。然后移除不等于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 循环:P尝试不同的方法来完成相同的任务。

5个回答

24

我希望我理解你的问题。你提到了“字典数组”,但是在你发布的代码中并没有字典数组。

据我所知,你想知道如何查找found数组中所有itemName等于filterItemName属性的条目。

如果是这样,你只需要执行以下操作:

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

就这样。


其他一些想法:

如果你想搜索itemName包含filterItemName的项,你可以像这样做:

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

如果你想进行不区分大小写搜索,你也可以使用lowercased()函数。

如果你想将找到的元素的属性返回到一个数组中:

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


1
哦,这就是我缺少的东西。之前我写了 let foundItems = found.filter{ 0$.itemName == "(filterItemName)"},但我得到的是所有数组,而不仅仅是等于 filterItemName 的那些。映射操作并不必要,因为我需要整个数组以便在项目后面进行注释。我想这完全是我所需要的。该死,我已经花了几天时间来处理一个简单的逻辑语句。现在我只需要将该数组附加到使用我的注释 circleQuery 的数组中,我想我已经解决了它。我会去检查一下,看看它是否正是我所需要的...谢谢。 - Cory Billeaud
我犹豫了,因为我将要在应用商店发布这个应用,我改变了我的类变量和函数变量的名称。我已经独自开发了这个应用超过一个月的时间。我希望能够获得一些广告收入,并有可能出售它,因为我最近失业了。再次感谢。 - Cory Billeaud
1
是的,let foundItems = found.filter { $0.itemName.contains(filterItemName) } 这个解决方案正是我所寻找的,真不敢相信我花了这么长时间在一个如此简单的问题上。我应该几天前就应该发布这个问题。 - Cory Billeaud
2
一个好的编程建议是,如果你遇到某些问题超过一天了,请寻求帮助。有时候仅仅是说出来就足够了,有时候别人会像我一样看到你完全走了错误的路。这种情况有时候发生在每个人身上。祝你在项目中好运。 - par

11

按照以下方法对字典数组进行排序

var dict:[[String:AnyObject]] = sortedArray.filter{($0["parentId"] as! String) == "compareId"}

「过滤器」函数循环遍历集合中的每个项目,返回一个仅包含满足包含条件的项目的集合。

我们可以从这个字典数组中获取单个对象,您可以使用以下代码。

var dict = sortedArray.filter{($0["parentId"] as! String) == "compareId"}.first

或者

 let dict = sortedArray.filter{ ($0["parentId"] as! String) == "compareId" }.first

0

这里我使用CoreData,有一个字典数组。 在这里,我过滤键paymentToInvoice的值为发票数组,然后键invoiceToPeople包含People Dictionary,然后搜索FirstName、lastName、Organization多个键包含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

使用数组字典对象中的谓词进行本地搜索过滤器,此代码适用于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()
    }


  }

0
如果你想根据字典数组中的键值进行过滤,可以按照以下方法实现。
incidentTransitionArray.filter{($0.isDisabled) == false}

这里的 incidentTransitionArray 是一个字典数组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接