2014-12-05 260 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