2014-12-05 47 views
0

我有一個字符串數組數組,我從核心數據中提取並轉換爲雙精度數。一旦我完成了這個任務,我希望得到他們的總和,但是我得到一個錯誤。我試過這樣:在swift中獲取數組的總和

override func viewDidLoad() { 
    super.viewDidLoad() 

     //CoreData 
     let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate 
     let managedContext : NSManagedObjectContext = appDelegate.managedObjectContext! 
     var fetchRequest = NSFetchRequest(entityName: "Log") 
     fetchRequest.returnsObjectsAsFaults = false; 
     var results: NSArray = managedContext.executeFetchRequest(fetchRequest, error: nil)! 

     if (results.count > 0) { 
      for res in results { 
       var totalWorkTimeInHoursString = res.valueForKey("totalWorkTimeInHoursString") as String 
       //get double value of strings array 
       var totalWorkTimeInHoursNSString = NSString(string: totalWorkTimeInHoursString) 
       var totalWorkTimeInHoursNSStringDoubleValue = totalWorkTimeInHoursNSString.doubleValue 
       lastLogHoursWorked.text = "\(totalWorkTimeInHoursString) hours" 
       totalHoursWorkedSum.text = "\(totalWorkTimeInHoursNSStringDoubleValue)" 

       let sum = totalWorkTimeInHoursNSStringDoubleValue.reduce(0,+) 
        //throws an error saying 'Double' does not have a member named 'reduce' 

       println(totalWorkTimeInHoursNSStringDoubleValue) 
        //lists the array of doubles in console successfully 
       println(sum) 
        //checking to see if 'sum' works properly 

     } 
     }else { 
      println("zero results returned, potential error") 
     } 
} 

我是否正確地接近這個?我錯過了什麼?

+0

根據該docs(https://developer.apple.com/library/mac/documentation/General/Reference/SwiftStandardLibraryReference/Array.html)'reduce'應用於* collection * - 不是double。 – 2014-12-07 16:37:38

回答

3

ReduceArray上的函數。當你說array.reduce(0, +)時,你所說的是,「這是一個雙精度數組,通過對元素應用+操作,將元素合併爲一個單一值,從0開始,作爲值」。

您不能reduce單個值。

+0

但在這種情況下,「totalWorkTimeInHoursNSStringDoubleValue」是雙精度數組是否正確?至少它在打電話時向控制檯輸出一個雙精度數組。有沒有其他的方式來實現我的目標? – Leighton 2014-12-05 19:32:57

+0

不,它不是一個數組,它是一個Double。如果您看到一系列雙打,請剪切/粘貼您看到的內容。 – 2014-12-05 20:06:09

+0

@Leighton是的,您已將字符串轉換爲雙精度值。這是雙倍的。 – 2014-12-07 16:39:22

1
extension Array { 

    func sumInt() -> Int { return map { $0 as Int }.reduce(0) { $0 + $1 } } 
    func sumUInt() -> UInt { return map { $0 as UInt }.reduce(0) { $0 + $1 } } 
    func sumUInt8() -> UInt8 { return map { $0 as UInt8 }.reduce(0) { $0 + $1 } } 
    func sumUInt16() -> UInt16 { return map { $0 as UInt16 }.reduce(0) { $0 + $1 } } 
    func sumUInt32() -> UInt32 { return map { $0 as UInt32 }.reduce(0) { $0 + $1 } } 
    func sumUInt64() -> UInt64 { return map { $0 as UInt64 }.reduce(0) { $0 + $1 } } 
    func sumDouble() -> Double { return map { $0 as Double }.reduce(0) { $0 + $1 } } 
    func sumFloat() -> Float { return map { $0 as Float }.reduce(0) { $0 + $1 } } 
    func sumCGFloat()-> CGFloat{ return map { $0 as CGFloat}.reduce(0) { $0 + $1 } } 

    // make it type safe 

    func sum() -> T { 
     if !isEmpty { 
      if self[0] is Int { return (sumInt()  as T) } 
      if self[0] is UInt { return (sumUInt() as T) } 
      if self[0] is UInt8 { return (sumUInt8() as T) } 
      if self[0] is UInt16 { return (sumUInt16() as T) } 
      if self[0] is UInt32 { return (sumUInt32() as T) } 
      if self[0] is UInt64 { return (sumUInt64() as T) } 
      if self[0] is Double { return (sumDouble() as T) } 
      if self[0] is Float { return (sumFloat() as T) } 
      if self[0] is CGFloat{ return (sumCGFloat() as T) } 
     } 
     return 0 as T 
    } 
} 

用法:

let inputArrayInt:[Int]=[1,2,3] 
let sumInt = inputArrayInt.sum()    // 6 

let inputArrayUInt:[UInt]=[1,2,3] 
let sumUInt = inputArrayUInt.sum()   // 6 

let inputArrayUInt8:[UInt8]=[1,2,3] 
let sumUInt8 = inputArrayUInt8.sum()   // 6 

let inputArrayUInt16:[UInt16]=[1,2,3] 
let sumUInt16 = inputArrayUInt16.sum()  // 6 

let inputArrayUInt32:[UInt32]=[1,2,3] 
let sumUInt32 = inputArrayUInt32.sum()  // 6 

let inputArrayUInt64:[UInt64]=[1,2,3] 
let sumUInt64 = inputArrayUInt64.sum()  // 6 

let inputArrayDouble:[Double]=[1.0,2.0,3.0] 
let sumDouble = inputArrayDouble.sum()  // 6.0 

let inputArrayFloat:[Float]=[1.0,2.0,3.0] 
let sumFloat = inputArrayFloat.sum()   // 6.0 

let inputArrayCGFloat:[CGFloat]=[1.0,2.0,3.0] 
let sumCGFloat = inputArrayCGFloat.sum()  // 6.0 
3

看你的代碼,我推斷,results是字典的數組,每個字典有totalWorkTimeInHoursString鍵,它的值是雙號的字符串表示。

我會使用位功能辦法解決它,使用filtermapreduce

if results.count > 0 { 
    var res = results as [NSDictionary] 

    var result = res.filter { $0["totalWorkTimeInHoursString"] is String } 
     .map { ($0["totalWorkTimeInHoursString"] as NSString).doubleValue } 
     .reduce (0, +) 
} 

的代碼做什麼:

  • results數組轉換成NSDictionary
  • 數組
  • 通過刪除沒有totalWorkTimeInHoursString密鑰或其對應聲明的所有元素(它們是字典)來過濾數組onding值不是字符串
  • 轉換陣列中的每個元素到一個雙,通過提取對應於totalWorkTimeInHoursString鍵的值,轉換爲NSString再到Double
  • 應用reduce方法,並傳遞+操作者總結了所得的Double

array這是我測試我的解決方案與所述數據,在操場:

var results: NSArray = [ 
    ["totalWorkTimeInHoursString": "10.0"], 
    ["totalWorkTimeInHoursString": "5.0"] 
] 
+0

剛剛嘗試過,它會拋出一個錯誤「致命錯誤:NSArray元素無法匹配Swift數組元素類型」 – Leighton 2014-12-05 20:24:56

+0

「results」中的某些元素可能不是字典嗎?如果沒有,您是否還有關於該錯誤的其他詳細信息? – Antonio 2014-12-05 20:31:11

+0

在這一點上,我試圖做的是檢索核心數據屬性(這是數字存儲爲字符串)的列表並獲得它們的總和。我目前已經將它們全部加載到tableview中,但在這個視圖控制器中,我只是想要一個標籤和他們的總和。希望這能解釋我的情況好一點嗎?謝謝你的耐心! :) – Leighton 2014-12-05 20:39:31