2016-03-29 31 views
2

私は配列を持っています、var hoursPlayed = String 彼らはtableViewにあり、すべての数字です。
文字列配列に数値を追加するには? Swift

let sum= hoursPlayed.reduce(0.0,combine:{$0+Float($1)!}) 

基本的には、配列を反復処理し、すべての値を蓄積している:スウィフト2

+0

http://stackoverflow.com/questions/24795130/finding-sum-of-elements-in-swift-arrayは基本的な考え方はもちろん正確であるが、この –

答えて

2

にあなたは減らす使用することができます。それは文字列の配列なので、わかりやすくするために、私はFloatにアンラップされた力を持っていますが、オプションのものをチェックする必要があります。 reduce関数は2つの引数を引数としてクロージャをとります。ドル記号とは、第1と第2を取り、それらを合計することを意味します。 これで、配列の要素数に簡単に分けて、avergaeを持つことができます。
objCの世界であれば、キー値コーディングと@avg演算子を使うのがいいでしょう。
[更新日]
Darkoが投稿した最初のバージョンはコンパイルされません。最初の引数をFloatに変換する際にエラーが発生しました。これは、reduceが初期値をとり、Floatという名前を付けて変換する必要がないためです。

+0

参照返すことコンパイルされません。 – Darko

+0

申し訳ありません私は編集中の私のオフィスにいるときに私はiPadで書いています – Andrea

2
let array = ["10.0", "30.0"] 
if array.count > 0 { 
    let average = array.reduce(0.0, combine: {$0 + (Double($1) ?? 0.0)})/Double(array.count) 
    print(average) // 20.0 
} 

$ 0は常にDoubleであることが保証されているため、変換する必要はありません。 $ 0は初期値から推定され、0.0:Doubleと宣言されています。

array.countが、私はそれらを追加してダブルスとreduceに文字列を変換するためにflatMapの組み合わせを使用したい0

+0

ありがとう!それは働いた –

+0

これはイディオムスウィフトの素敵なイラストです。 '?? 'の使用は、強制アンラッピングよりもずっと優れています。うまくいった。 (Commentは20.0に変更する必要がありますが、 'Double'を' String'ではなく正しく生成します) –

1

スルー分裂を防ぐためにチェックする必要があります。

let doubles = array.flatMap { Double($0) } 
let average = doubles.reduce(0.0, combine:+)/Double(doubles.count) 

let average = array.map({ Double($0)! })/Double(array.count) 
:あなたは、彼らのすべては、あなたがそれを簡素化することができます変換知っている場合

flatMapを使用すると、Doubleに変換することはできません配列のエントリからあなたを守ります

一つの最後のオプションは、それはあなたがより一般的に使用することがあります何かのように思える場合は平均関数で配列を拡張し、flatMapおよび/またはマップと組み合わせて、それを使用することです:ダルコのアプローチを修正

protocol ArithmeticType { 
    static func zero() -> Self 

    func +(lhs:Self, rhs:Self) -> Self 
    func -(lhs:Self, rhs:Self) -> Self 
    func /(lhs:Self, rhs:Self) -> Self 
    func *(lhs:Self, rhs:Self) -> Self 

    init(_ number:Int) 
} 

extension Double : ArithmeticType { 
    static func zero() -> Double { 
     return 0.0 
    } 
} 

extension Array where Element : ArithmeticType { 
    func average() -> Element { 
     return reduce(Element.zero(), combine:+)/Element(count) 
    } 
} 

let avg = array.flatMap { Double($0) }.average() 
+0

flatMapのバージョンは非常にクリーンで直感的です。唯一の欠点は、配列上で2回反復する必要があることです。しかし、ほとんどの状況では、アプリケーションの開発はこれではごくわずかです。 +1 – Darko

+0

少なくとも1つのバージョンは、反復を1回だけ実行し、複数の配列を作成するのを避けるために遅延を使用しました。 –

1

、どのStringがDoubleに変換可能かどうかを考慮する。空の配列のためには、0.0

let array = ["10.0", "31.2", "unknown", ""] 

func avg(arr: [String])->Double { 
    let arr = array.flatMap(Double.init) 
    var avg = 0.0 
    if arr.count > 0 { 
     avg = arr.reduce(0.0, combine: +)/Double(arr.count) 
    } 
    return avg 
} 

let a = avg(array) 
print(a) // 20.6 
+0

それは素晴らしいです。 flatMap(Double.init)について説明できますか? – Darko

+0

なぜこれが気に入りませんか?'flatMap {Double($ 0)}' – Darko

+0

@Darko構文が異なるだけで、結果は同じです... – user3441734

関連する問題