Swift配列の要素の合計を見つける


228

整数の配列の合計をすばやく見つけるための最も簡単な(最良の)方法は何ですか?倍数と呼ばれる配列があり、倍数の合計を知りたいのですが。

回答:


466

これは私が見つけることができる最も簡単な/最短の方法です。

Swift 3およびSwift 4:

let multiples = [...]
let sum = multiples.reduce(0, +)
print("Sum of Array is : ", sum)

スウィフト2:

let multiples = [...]
sum = multiples.reduce(0, combine: +)

さらに詳しい情報:

これは、Arrayのreduceメソッド(ここに記載されているドキュメント)を使用して、「提供されたクロージャーを再帰的に適用することにより、要素のコレクションを単一の値に減らす」ことができます。初期値として0を指定し、基本的にクロージャを指定し{ $0 + $1 }ます。もちろん、これをSwiftのローリング方法と同じように、1つのプラス記号に簡略化できます。


42
この回答をありがとう。それは素晴らしい作品と私は、カスタムクラスの配列を持つ私の例のコードを追加したい:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
リボルZapletal

2
良い答えですが、パラメータ名がありませんcombine。する必要がありますmultiples.reduce(0, combine: +)
Evgenii、2015年

2
forループよりも高速ですか?
ロレンソ2016年

1
@SwiftMatt flatMap最初にon を使用して、1次元配列にフラット化してみてください。multiArray.flatMap{$0}.reduce(0, combine: +)
Samah

2
@lorenzo-最新のSwiftとXCode(UInt32のオーバーフローを防ぐために256でキャップされた1,000,000のUInt32ランダム値で満たされた単純な配列)を備えたiPhone 7でのテストは、興味深いことに、「for」ループが単なる髪の速い(1.941秒対2.137秒)ことを示していますただし、その利点は100,000の値(各0.23秒)では存在しません。私見、32MBの配列を扱う場合でも、コードの明快さは、ここでは非常に小さなパフォーマンスコストの価値があります。
トム・ディブル

84

オブジェクトのプロパティを合計する3以上の 1つのライナー

var totalSum = scaleData.map({$0.points}).reduce(0, +)

ここで、pointsは、削減しようとしているカスタムオブジェクトscaleDataのプロパティです。



22

Swift 4では、シーケンス要素を数値プロトコルに制限して、次のようにシーケンス内のすべての要素の合計を返すこともできます。

extension Sequence where Element: Numeric {
    /// Returns the sum of all elements in the collection
    func sum() -> Element { return reduce(0, +) }
}

編集/更新:

Xcode 10.2•Swift 5以降

シーケンス要素を新しいAdditiveArithmeticプロトコルに制約するだけで、コレクション内のすべての要素の合計を返すことができます

extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element {
        return reduce(.zero, +)
    }
}

Xcode 11•Swift 5.1以降

extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element { reduce(.zero, +) }
}

let numbers = [1,2,3]
numbers.sum()    // 6

let doubles = [1.5, 2.7, 3.0]
doubles.sum()    // 7.2

1
素晴らしい、素晴らしい解決策!
サビランド

11

これも機能します:

let arr = [1,2,3,4,5,6,7,8,9,10]
var sumedArr = arr.reduce(0, combine: {$0 + $1})
print(sumedArr)

結果は次のようになります:55


10

Swift 4の例

class Employee {
    var salary: Int =  0
    init (_ salary: Int){
        self.salary = salary
    }
}

let employees = [Employee(100),Employee(300),Employee(600)]
var sumSalary = employees.reduce(0, {$0 + $1.salary}) //1000

9

スウィフト3

一般的なオブジェクトの配列があり、オブジェクトのプロパティを合計したい場合:

class A: NSObject {
    var value = 0
    init(value: Int) {
       self.value = value
    }
}

let array = [A(value: 2), A(value: 4)]      
let sum = array.reduce(0, { $0 + $1.value })
//                           ^       ^
//                        $0=result  $1=next A object
print(sum) // 6 

短い形式にもかかわらず、多くの場合、古典的なforサイクルを好むことがあります。

let array = [A(value: 2), A(value: 4)]
var sum = 0
array.forEach({ sum += $0.value}) 
// or
for element in array {
   sum += element.value
}

1
ciao Luca、これが私の解決策です:array.map({$ 0.value})。reduce(0、+)
Ivailo

このようにして、より多くのコードを記述し、複雑さを増加させます。
Luca Davanzo

6

簡単な方法はどうですか

for (var i = 0; i < n; i++) {
 sum = sum + Int(multiples[i])!
}

// n =配列の要素数


Swift 3では、Cスタイルのループが言語から削除されたため、これは無効になっています。代わりにfor-inループを使用して、Swiftはインデックスの内部で追跡を続けます。
donarb 2017

1
それはそのままでは機能しません。最初に合計を0に初期化する必要があります。reduceの優れた点は、初期値を考えるように思い出させることです。
MarkAurelius 2017年

var sum = 0 ; for n in multiples { sum += n }リデュースを使用しますが。
JeremyP 2018年

2

考えられる解決策:プレフィックス演算子を定義します。APL(例:GNU APL)の場合と同様に、reduce "+ /"演算子のように

ここで少し異なるアプローチ。

プロトコルジェネリック型を使用すると、この演算子をDouble、Float、およびInt配列型で使用できます

protocol Number 
{
   func +(l: Self, r: Self) -> Self
   func -(l: Self, r: Self) -> Self
   func >(l: Self, r: Self) -> Bool
   func <(l: Self, r: Self) -> Bool
}

extension Double : Number {}
extension Float  : Number {}
extension Int    : Number {}

infix operator += {}

func += <T:Number> (inout left: T, right: T)
{
   left = left + right
}

prefix operator +/ {}

prefix func +/ <T:Number>(ar:[T]?) -> T?
{
    switch true
    {
    case ar == nil:
        return nil

    case ar!.isEmpty:
        return nil

    default:
        var result = ar![0]
        for n in 1..<ar!.count
        {
            result += ar![n]
        }
        return result
   }
}

次のように使用します:

let nmbrs = [ 12.4, 35.6, 456.65, 43.45 ]
let intarr = [1, 34, 23, 54, 56, -67, 0, 44]

+/nmbrs     // 548.1
+/intarr    // 145

(Swift 2.2用に更新、Xcodeバージョン7.3でテスト済み)


これに関する1つの問題は、多くの場合(少なくとも、大きな配列を処理する場合)、合計がコンポーネントとは異なる型である必要があることです。たとえば、0から2 ^ 32-1の色域を実行している100万個のUInt32がある場合(たとえば、arc4random()によって生成されます)、それらを追加すると、毎回UInt32の「合計」値がオーバーフローします。
トム・ディブル

2

Swift 3.0

私は同じ問題がありました、私はドキュメントAppleでこの解決策を見つけました。

let numbers = [1, 2, 3, 4]
let addTwo: (Int, Int) -> Int = { x, y in x + y }
let numberSum = numbers.reduce(0, addTwo)
// 'numberSum' == 10

しかし、私の場合、オブジェクトのリストがあり、リストの値を変換する必要がありました。

let numberSum = self.list.map({$0.number_here}).reduce(0, { x, y in x + y })

この仕事は私にとって。


0
@IBOutlet var valueSource: [MultipleIntBoundSource]!

private var allFieldsCount: Int {
    var sum = 0
    valueSource.forEach { sum += $0.count }
    return sum
}

ネストされたパラメータにこれを使用しました


0

単純にする...

var array = [1, 2, 3, 4, 5, 6, 7, 9, 0]
var n = 0
for i in array {
    n += i
}
print("My sum of elements is: \(n)")

出力:

私の要素の合計は:37


0

私にとっては、プロパティを使用してこのようなものでした

    let blueKills = match.blueTeam.participants.reduce(0, { (result, participant) -> Int in
        result + participant.kills
    })

-2

スウィフト3

ここに表示されるすべてのオプションから、これは私のために働いたものです。

let arr = [6,1,2,3,4,10,11]


var sumedArr = arr.reduce(0, { ($0 + $1)})
print(sumedArr)

これは別の回答のコピーにすぎません
Ashley Mills


-4

これが私のアプローチです。しかし、私は最良の解決策はユーザーユーザー名tbdからの答えであると信じています

var i = 0 
var sum = 0
let example = 0
for elements in multiples{
    i = i + 1
    sum = multiples[ (i- 1)]
    example = sum + example
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.