【问题标题】:Sort Swift Array of Dictionaries by Value of a Key按键的值对 Swift 字典数组进行排序
【发布时间】:2015-05-25 22:26:55
【问题描述】:

我正在尝试对由字典组成的 Swift 数组进行排序。我在下面准备了一个工作示例。目标是按字典中的“d”元素对整个数组进行排序。我准备了这个可以放入 Swift 项目的工作示例:

var myArray = Array<AnyObject>()
var dict = Dictionary<String, AnyObject>()

dict["a"] = "hickory"
dict["b"] = "dickory"
dict["c"] = "dock"
dict["d"] = 5

myArray.append(dict)

dict["a"] = "three"
dict["b"] = "blind"
dict["c"] = "mice"
dict["d"] = 6

myArray.append(dict)

dict["a"] = "larry"
dict["b"] = "moe"
dict["c"] = "curly"
dict["d"] = 2

myArray.append(dict)

println(myArray[0])
println(myArray[1])
println(myArray[2])
}

这会导致以下输出到日志:

{
    a = hickory;
    b = dickory;
    c = dock;
    d = 5;

}
{
    a = three;
    b = blind;
    c = mice;
    d = 6;
}
{
    a = larry;
    b = moe;
    c = curly;
    d = 2;
}

目标是按“d”元素对数组进行排序,这样上面的输出就会变成下面的样子(基于“d”的数字顺序:'2,5,6'):

{
    a = larry;
    b = moe;
    c = curly;
    d = 2;
}
{
    a = hickory;
    b = dickory;
    c = dock;
    d = 5;
}
{
    a = three;
    b = blind;
    c = mice;
    d = 6;
}

还有一些其他问题看起来很相似,但是当您查看它们时,很明显他们并没有解决这个问题。感谢您的帮助。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    要声明,如果需要将其保留为 AnyObject,则必须显式转换:

    var myArray = Array<AnyObject>()
    var dict = Dictionary<String, AnyObject>()
    
    dict["a"] = ("hickory" as! AnyObject)
    dict["b"] = ("dickory" as! AnyObject)
    dict["c"] = ("dock" as! AnyObject)
    dict["d"] = (6 as! AnyObject)
    
    myArray.append(dict as! AnyObject)
    
    dict["a"] = ("three" as! AnyObject)
    dict["b"] = ("blind" as! AnyObject)
    dict["c"] = ("mice" as! AnyObject)
    dict["d"] = (5 as! AnyObject)
    
    
    myArray.append(dict as! AnyObject)
    
    dict["a"] = ("larry" as! AnyObject)
    dict["b"] = ("moe" as! AnyObject)
    dict["c"] = ("curly" as! AnyObject)
    dict["d"] = (4 as! AnyObject)
    
    myArray.append(dict as! AnyObject)
    

    不附加,你可以这样做:

    var myArray: [AnyObject] = [ ([
        "a" : ("hickory" as! AnyObject),
        "b" : ("dickory" as! AnyObject),
        "c" : ("dock" as! AnyObject),
        "d" : (6 as! AnyObject)
      ] as! AnyObject), ([
        "a" : ("three" as! AnyObject),
        "b" : ("blind" as! AnyObject),
        "c" : ("mice" as! AnyObject),
        "d" : (5 as! AnyObject)
      ] as! AnyObject), ([
        "a" : ("larry" as! AnyObject),
        "b" : ("moe" as! AnyObject),
        "c" : ("curly" as! AnyObject),
        "d" : (4 as! AnyObject)
      ] as! AnyObject)
    ]
    

    这会给你同样的结果。虽然,如果只需要更改字典中的值对象,则不需要对数组的元素进行强制转换:

    var myArray: [Dictionary<String, AnyObject>] = [[
        "a" : ("hickory" as! AnyObject),
        "b" : ("dickory" as! AnyObject),
        "c" : ("dock" as! AnyObject),
        "d" : (6 as! AnyObject)
      ], [
        "a" : ("three" as! AnyObject),
        "b" : ("blind" as! AnyObject),
        "c" : ("mice" as! AnyObject),
        "d" : (5 as! AnyObject)
      ], [
        "a" : ("larry" as! AnyObject),
        "b" : ("moe" as! AnyObject),
        "c" : ("curly" as! AnyObject),
        "d" : (4 as! AnyObject)
      ]
    ]
    

    然后,要进行排序,您可以使用 sort() 闭包,它对 Array 进行就地排序。您提供的闭包接受两个参数(名为 $0 和 $1),并返回一个 Bool。如果 $0 在 $1 之前排序,则闭包应该返回 true,如果在 $1 之后排序,则返回 false。要做到这一点,你必须投入很多:

    //myArray starts as: [
    //  ["d": 6, "b": "dickory", "c": "dock", "a": "hickory"],
    //  ["d": 5, "b": "blind", "c": "mice", "a": "three"],
    //  ["d": 4, "b": "moe", "c": "curly", "a": "larry"]
    //]
    
    myArray.sort{
      (($0 as! Dictionary<String, AnyObject>)["d"] as? Int) < (($1 as! Dictionary<String, AnyObject>)["d"] as? Int)
    }
    
    //myArray is now: [
    //  ["d": 4, "b": "moe", "c": "curly", "a": "larry"],
    //  ["d": 5, "b": "blind", "c": "mice", "a": "three"],
    //  ["d": 6, "b": "dickory", "c": "dock", "a": "hickory"]
    //]
    

    【讨论】:

    • 不,这不起作用。它导致了一个错误:找不到接受类型为 '(Array,(,) -> _)' 的参数列表的 'sorted' 的重载,你可以试试这个吗XCode 看看你的想法是否有效?更新:等等,我尝试使用您提供的整个代码块,其中还包括更新的数组声明。错误消失了,但排序不起作用。我得到:[b:dickory,a:hickory,c:dock] [b:blind,a:三,c:老鼠] [b:moe,a:larry,c:curly]
    • 是的,您必须像我上面那样更改声明。 var myArray = Array&lt;Dictionary&lt;String, String&gt;&gt;() var dict = Dictionary&lt;String, String&gt;()
    • 请阅读我之前更新的回复。错误消失了,但排序不起作用。我将您的代码与 println(myArray[0]) println(myArray[1]) println(myArray[2]) 一起直接粘贴到 XCode 中并得到:[b:dickory,a:hickory,c:dock] [b:blind , a: 三, c: 老鼠] [b: moe, a: larry, c: curly]
    • 最后一行应该是myArray.sort() {$0["c"] &lt; $1["c"]}var newArray = sorted(myArray){$0["c"] &lt; $1["c"]}。 Sorted 会创建一个新数组,而 sort 不会。
    • 最后一行是一个语句,它返回我在评论中的内容 - 我将对其进行一些更改以使其更清晰。
    【解决方案2】:

    在 Swift 3 & 4 中对字典数组进行排序

    let sortedResults = (userArray as NSArray).sortedArray(using: [NSSortDescriptor(key: "name", ascending: true)]) as! [[String:AnyObject]]
    

    【讨论】:

    • 如果您有 1、2、10、100 等键值,则效果不佳
    【解决方案3】:

    编辑/更新:Xcode 11 • Swift 5

    var array: [[String:Any]] = []
    var dict: [String: Any] = [:]
    
    dict["a"] = "hickory"
    dict["b"] = "dickory"
    dict["c"] = "dock"
    dict["d"] = 5
    
    array.append(dict)
    
    dict["a"] = "three"
    dict["b"] = "blind"
    dict["c"] = "mice"
    dict["d"] = 6
    
    array.append(dict)
    
    dict["a"] = "larry"
    dict["b"] = "moe"
    dict["c"] = "curly"
    dict["d"] = 2
    
    array.append(dict)
    

    let sortedArray = array.sorted { $0["d"] as? Int ?? .zero < $1["d"] as? Int ?? .zero }
    
    print(sortedArray)  // "[[b: moe, a: larry, d: 2, c: curly], [b: dickory, a: hickory, d: 5, c: dock], [b: blind, a: three, d: 6, c: mice]]"
    

    【讨论】:

      【解决方案4】:

      在斯威夫特中

      let mySortedArray = myArray.sorted(by: {(int1, int2)  -> Bool in
          return ((int1 as! NSDictionary).value(forKey: "d") as! Int) < ((int2 as! NSDictionary).value(forKey: "d") as! Int) // It sorted the values and return to the mySortedArray
        }) 
      
      print(mySortedArray)
          
      myArray.removeAllObjects() // Remove all objects and reuse it
          
      myArray.addObjects(from: mySortedArray)
          
      print(mySortedArray)
      

      按升序排列字典值数组很容易。它不需要任何循环。

      【讨论】:

        【解决方案5】:

        当我们解析数据时,我们可以使用 NSSortDescriptor 进行排序

        let dataDict1 = responseDict.valueForKey("Data")
        self.customerArray = dataDict1!.valueForKey("Customers") as! NSMutableArray
        
        var tempArray = NSMutableArray()
        for  index in self.customerArray {
           tempArray.addObject(index.valueForKey("Customer") as! NSMutableDictionary)
        }
        
        let descriptor: NSSortDescriptor =  NSSortDescriptor(key: "name", ascending: true, selector: "caseInsensitiveCompare:")
        let sortedResults: NSArray = tempArray.sortedArrayUsingDescriptors([descriptor])
        self.customerArray = NSMutableArray(array: sortedResults)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-08-12
          • 1970-01-01
          • 2016-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-18
          相关资源
          最近更新 更多