2015-10-16 62 views
0

我有一个字典数组,我的字典是类型[String:AnyObject]。下面是一些数据:在Swift中对多个条件的字典数组进行排序

[{ 
    name = Joe; 
    score = 50; 
    favorite = Phone; 
    startDate = "2015-10-15"; 
    startingTime = "2015-10-15 19:00:00 +0000"; 
    finished = "<null>"; 
}, { 
    name = Mark; 
    score = 60; 
    favorite = Phone; 
    startDate = "2015-10-16”; 
    startingTime = "2015-10-16 19:00:00 +0000"; 
    finished = "<null>"; 
}, { 
    name = Joe; 
    score = 30; 
    favorite = Phone; 
    startDate = "2015-10-15"; 
    startingTime = "2015-10-15 19:00:00 +0000"; 
    finished = "<null>"; 
}] 

我要的是能够理清这些最早由名称,然后通过startingTime,那么如果这些都匹配,那么按分数(我的分数存储为一个字符串,虽然)。

我知道这是非常错误的,但我键入:

test.sort({ $0.name! < $1.name! }) 

这给了我一个错误“无法调用‘排序’类型的参数列表“((_,_) - > _) ”“。

任何人都可以阐明如何做到这一点?

**更新为具有与视图控制器代码的答案

import UIKit 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     var allArray = [AnyObject]() 
     var array = [String:AnyObject]() 

     array["name"] = "Joe" 
     array["score"] = 50 as Int 
     array["favorite"] = "Phone" 
     array["startDate"] = "2015-10-15" 
     let date = NSDate() 
     array["date"] = date 
     array["finished"] = nil 
     allArray.append(array) 

     array["name"] = "Mark" 
     array["score"] = 60 as Int 
     array["favorite"] = "Phone" 
     array["startDate"] = "2015-10-16" 
     array["date"] = date 
     array["finished"] = nil 
     allArray.append(array) 

     array["name"] = "Joe" 
     array["score"] = 30 as Int 
     array["favorite"] = "Phone" 
     array["startDate"] = "2015-10-15" 
     array["date"] = date 
     array["finished"] = nil 
     allArray.append(array) 
     println(allArray) 

     allArray.sort { 
      if let name0 = $0["name"] as? String, name1 = $1["name"] as? String 
       where name0 != name1 { 
        return name0 < name1 
      } 

      // You said 'startingTime' in your question your code showed 'date' 
      if let date0 = $0["date"] as? NSDate, date1 = $1["date"] as? NSDate 
       where date0.timeIntervalSince1970 != date1.timeIntervalSince1970 { 
        return date0.timeIntervalSince1970 < date1.timeIntervalSince1970 
      } 

      // You have 'score' as String. I think you would want a numeric type instead 
      return ($0["score"] as! Int) < ($1["score"] as! Int) 
     } 

     println(allArray) 

    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

谢谢!

+0

您的数据看起来像是一种奇怪的JSON,它使用了等号和分号分隔符,并且没有引用字符串。可能会修复第一个 – spirographer

+0

@ spirographer,这将是NSDictionary – jtbandes

+0

@jbandes这不是我认识的任何语法。请参阅下面的答案,了解编译的语法。 – spirographer

回答

0

只是将我的解决方案添加到已经很拥挤的答案中,因为现有的答案都没有让我满意。因为你用AnyObject作为价值型

// allArray is as initiated in your viewDidLoad method 

let sortedArray = allArray.sort { 
    if let name0 = $0["name"] as? String, name1 = $1["name"] as? String 
     where name0 != name1 { 
      return name0 < name1 
    } 

    // You said 'startingTime' in your question but your code showed 'date' 
    if let date0 = $0["date"] as? NSDate, date1 = $1["date"] as? NSDate 
     where date0.timeIntervalSince1970 != date1.timeIntervalSince1970 { 
      return date0.timeIntervalSince1970 < date1.timeIntervalSince1970 
    } 

    // You have 'score' as String. I think you would want a numeric type instead 
    return ($0["score"] as! Int) < ($1["score"] as! Int) 
} 

的代码与石膏千疮百孔。

+0

感谢您的答案!我把我们的let排序数组部分,因为它不会分配,但我不需要它,因为我只需要allArray排序。我将更新问题中的代码。 – Joe

1

如果编译器变得像这样奇怪,试试更加明确地使用闭包参数。

这种排序方法似乎适用于我。

arr = arr.sort { a, b in 
    if a["name"] == b["name"] { 
     if a["startingTime"] == b["startingTime"] { 
      return a["score"] > b["score"] 
     } 
     return a["startingTime"] > b["startingTime"] 
    } else { 
     return a["name"] > b["name"] 
    } 
} 
0

它看起来像这个作品中,后卫是只是这样我就不必应对攀比展开(我爱因为这个后卫,使得代码更清洁IMO)

let test : [[String:AnyObject]] = [["name":"joe", "time":1, "score":5], ["name":"joe", "time":1, "score":3], ["name":"joe", "time":1, "score":7]] 

let sorted = test.sort{ 
    guard let name = $0["name"] as? String, 
    let time = $0["time"] as? Int, 
    let score = $0["score"] as? Int, 
    let name1 = $1["name"] as? String, 
    let time1 = $1["time"] as? Int, 
    let score1 = $1["score"] as? Int else{ 
      //unwrapping failed, sort is going to be bad 
      return false 
    } 

    if name == name1 { 
     if time == time1 { 
      return score < score1 
     }else { 
      return time < time1 
     } 
    }else { 
     return name < name1 
    } 

} 

print(sorted) 
+0

我仍然使用Xcode 6.4有什么方法可以帮助我转换语法吗?如果这样做会有所帮助 – Joe

0

下面是一些使给定的代码更好地工作的代码片段。首先将这些添加到文件的开头,以使日期具有可比性。

public func ==(lhs: NSDate, rhs: NSDate) -> Bool { 
     return lhs === rhs || lhs.compare(rhs) == .OrderedSame 
    } 

    public func <(lhs: NSDate, rhs: NSDate) -> Bool { 
     return lhs.compare(rhs) == .OrderedAscending 
    } 

    extension NSDate: Comparable { } 

然后在你的方法使用下面的语法(这是SWIFT 2):

var allArray = [AnyObject]() 
    var array = [String:AnyObject]() 

    array["name"] = "Joe" 
    array["score"] = "50" 
    array["favorite"] = "Phone" 
    array["startDate"] = "2015-10-15" 
    let date = NSDate() 
    array["startingTime"] = date 
    array["finished"] = nil 
    allArray.append(array) 

    array["name"] = "Mark" 
    array["score"] = "60" 
    array["favorite"] = "Phone" 
    array["startDate"] = "2015-10-16" 
    array["startingTime"] = date 
    array["finished"] = nil 
    allArray.append(array) 

    array["name"] = "Joe" 
    array["score"] = "30" 
    array["favorite"] = "Phone" 
    array["startDate"] = "2015-10-15" 
    array["startingTime"] = date 
    array["finished"] = nil 
    allArray.append(array) 
    print(allArray) 

    allArray.sortInPlace { i,j in (i["name"] as! String) < (j["name"] as! String) || (i["startingTime"] as! NSDate) < (j["startingTime"] as! NSDate) } 

我不喜欢,如果你使用的语法这样虽然。这是一种更快捷的方式来声明一系列字典。

let xyz = [ 
     [ 
      "name" : "Joe", 
      "score" : 50, 
      "favorite" : "Phone", 
      "startDate" : "2015-10-15", 
      "startingTime" : "2015-10-15 19:00:00 +0000", 
      "finished" : "<null>" 
     ], [ 
      "name" : "Mark", 
      "score" : 60, 
      "favorite" : "Phone", 
      "startDate" : "2015-10-16", 
      "startingTime" : "2015-10-16 19:00:00 +0000", 
      "finished" : "<null>" 
     ], [ 
      "name" : "Joe", 
      "score" : 30, 
      "favorite" : "Phone", 
      "startDate" : "2015-10-15", 
      "startingTime" : "2015-10-15 19:00:00 +0000", 
      "finished" : "<null>" 
     ] 
    ] 
    var test = xyz.sort { ($0["name"] as! String) < ($1["name"] as! String) } 
相关问题