2015-10-16 60 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) } 
相關問題