【问题标题】:How do I sort an array of dictionary according to an array contents in Swift如何根据 Swift 中的数组内容对字典数组进行排序
【发布时间】:2017-02-16 21:06:07
【问题描述】:

我有一个字典数组。我需要对该数组进行排序。排序不应该像升序或降序,但它应该基于另一个数组内容。 例如:假设我有一个名为 array_unsorted 的数组,该数组包含很多字典对象,如 d1、d2、d3、d4 等。每个字典对象都有一个名为 key1 的键,每个字典对象都有不同的值对于该键,例如 KammyMaddyJessy。假设我有一个MaddyKammyJessy 的排序数组。现在字典的排序方式应该是第一个元素应该是字典对象,其中key1 should beMaddy`的值。

我不能使用 SortDescriptor,因为它会根据传递给它的键按升序或降序排序。

我已经尝试了我的解决方案,但我最终使用了这么多嵌套循环。我觉得我做的解决方案太可悲了,我什至不想在这里发布代码。

任何帮助将不胜感激。

编辑:可以有多个排序数组,但到目前为止我只考虑一个排序数组,然后我可以为多个排序数组编写代码。

【问题讨论】:

  • 分享一些相关的代码会更清晰:)
  • @iOS_Developer 给我们一个你期望的可编译输入和输出的例子。

标签: ios arrays swift


【解决方案1】:

这个怎么样:

使用 String 键和 Dictionary 类型的值创建一个新的空字典。叫它sourceItemsDict

遍历源数组中的字典,并将每个条目添加到新字典中,使用排序键作为字典键,并将数组条目作为值。

为您的排序结果创建一个新的空字典数组。叫它sortedArray

现在循环遍历具有所需顺序的数组。从sourceItemsDict 获取具有该密钥的项目并将其附加到sortedArray 的末尾。

应该可以,并且应该在 O(n) 时间内执行。

【讨论】:

    【解决方案2】:

    试试这个:

    func sort<T: Equatable>(arrayOfDict arr: [[String: T]], by key: String, order: [T]) -> [[String: T]] {
        return arr.sorted {
            guard let value0 = $0[key], let value1 = $1[key] else {
                return false
            }
            guard let index0 = order.index(of: value0), let index1 = order.index(of: value1) else {
                return false
            }
    
            return index0 < index1
        }
    }
    
    let array_unsorted = [
        ["name": "Kammy", "city": "New York"],
        ["name": "Maddy", "city": "Cupertino"],
        ["name": "Jessy", "city": "Mountain View"]
    ]
    let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
    let sortedByCity = sort(arrayOfDict: array_unsorted, by: "city", order: ["Cupertino", "Mountain View", "New York"])
    
    print(sortedByName)
    print(sortedByCity)
    

    您的问题留下了几个未解决的情况:

    1:如果字典中缺少键怎么办?

    let array_unsorted = [
        ["name": "Kammy", "city": "New York"],
        ["city": "Las Vegas"],
        ["name": "Maddy", "city": "Cupertino"],
        ["name": "Jessy", "city": "Mountain View"]
    ]
    
    let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
    

    拉斯维加斯应该出现在排序数组的开头还是结尾?

    2:如果不指定值的顺序怎么办?

    let array_unsorted = [
        ["name": "Amy"],
        ["name": "Kammy", "city": "New York"],
        ["name": "Maddy", "city": "Cupertino"],
        ["name": "Jessy", "city": "Mountain View"]
    ]
    
    let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
    

    现在应该将Amy 放在哪里?

    【讨论】:

    • 非常感谢您的回复。这解决了我的一半问题。作为未指定的 scnarios 的一部分,Las Vegas 应该在最后,并且没有缺少密钥。并且它修复了一半,因为下一级排序(在本例中为城市)应该应用于已经排序(基于名称)的数组。再次非常感谢。
    【解决方案3】:

    看看这个例子:

    let dic1 = ["name" : "a"]
    let dic2 = ["name" : "b"]
    let dic3 = ["name" : "c"]
    let dic4 = ["name" : "d"]
    let dic5 = ["name" : "e"]
    
    
    let unsorted_array = [dic2,dic5,dic1,dic4,dic3]
    
    func sortArrayByName(_ array:[[String:String]])->[[String:String]]{
        var sortedArray:[[String:String]] = [[String:String]]()
        var sortingOrder:[String] = [String]()
        for eachDic in array{
            if let name = eachDic["name"]{
                sortingOrder.append(name)
                sortingOrder.sort() // sorting logic here
    
                if sortedArray.isEmpty{
                    sortedArray.append(eachDic)
                } else {
                    let index = sortingOrder.index(of: name)!
                    sortedArray.insert(eachDic, at: index)
                }
            }
        }
    
        return sortedArray
    }
    
    let sorted_array = sortArrayByName(unsorted_array)
    

    【讨论】:

    • 这并不能解决 OP 问题。他们希望对字典数组进行排序,以便字典中排序键的顺序与字符串数组匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 2016-07-14
    相关资源
    最近更新 更多