Ermitteln der Summe der Elemente im Swift-Array


228

Was ist der einfachste (beste) Weg, um die Summe eines Arrays von ganzen Zahlen schnell zu finden? Ich habe ein Array namens Multiples und möchte die Summe der Multiples wissen.

Antworten:


465

Dies ist die einfachste / kürzeste Methode, die ich finden kann.

Swift 3 und Swift 4:

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

Swift 2:

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

Noch ein paar Infos:

Hierbei wird die Reduktionsmethode von Array verwendet (Dokumentation hier ), mit der Sie "eine Sammlung von Elementen durch rekursives Anwenden des bereitgestellten Abschlusses auf einen einzigen Wert reduzieren können". Wir geben 0 als Anfangswert und dann im Wesentlichen den Abschluss { $0 + $1 }. Natürlich können wir das zu einem einzigen Pluszeichen vereinfachen, denn so rollt Swift.


42
Danke für diese Antwort. Es funktioniert großartig und ich möchte nur meinen Beispielcode mit einer Reihe von benutzerdefinierten Klassen hinzufügen:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal

2
Tolle Antwort, aber fehlender Parametername combine. Sollte sein multiples.reduce(0, combine: +).
Evgenii

2
Ist es schneller als eine for-Schleife?
Lorenzo

1
@SwiftMatt Versuchen flatMapSie zuerst, ein darauf zu verwenden, um es auf ein Array mit einer einzigen Dimension zu reduzieren. multiArray.flatMap{$0}.reduce(0, combine: +)
Samah

2
@lorenzo - Tests auf einem iPhone 7 mit den neuesten Versionen von Swift und XCode (ein einfaches Array mit 1.000.000 UInt32-Zufallswerten, die auf 256 begrenzt sind, um einen UInt32-Überlauf zu verhindern) zeigen interessanterweise, dass die 'for'-Schleife nur ein Haar schneller ist (1,941 Sekunden gegenüber 2,137 Sekunden). , obwohl dieser Vorteil bei 100.000 Werten (jeweils 0,23 Sekunden) nicht vorhanden ist. Meiner Meinung nach ist die Klarheit des Codes auch bei 32-MB-Arrays nur einen sehr geringen Leistungsaufwand wert.
Tom Dibble

82

Swift 3+ One Liner, um die Eigenschaften von Objekten zu summieren

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

Wo Punkte ist die Eigenschaft in meinem benutzerdefinierten Objekt scaleData , die ich reduzieren möchte



22

In Swift 4 können Sie die Sequenzelemente auch auf das numerische Protokoll beschränken, um die Summe aller Elemente in der Sequenz wie folgt zurückzugeben

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

bearbeiten / aktualisieren:

Xcode 10.2 • Swift 5 oder höher

Wir können die Sequenzelemente einfach auf das neue AdditiveArithmetic- Protokoll beschränken, um die Summe aller Elemente in der Auflistung zurückzugeben

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

Xcode 11 • Swift 5.1 oder höher

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
Tolle, schöne Lösung!
Sabiland

11

Das funktioniert auch:

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

Das Ergebnis ist: 55


10

Swift 4 Beispiel

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

Swift 3

Wenn Sie ein Array generischer Objekte haben und eine Objekteigenschaft summieren möchten, dann:

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 

Trotz der kürzeren Form bevorzugen Sie oft den klassischen For-Cycle:

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, hier ist meine Lösung: array.map ({$ 0.value}). redu (0, +)
Ivailo Kanev

Auf diese Weise schreiben Sie mehr Code und erhöhen die Komplexität. Warum also?
Luca Davanzo

6

Wie wäre es mit dem einfachen Weg von

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

// wobei n = Anzahl der Elemente im Array


Beachten Sie, dass dies in Swift 3 nicht mehr gültig ist, da der C-Stil für Schleifen aus der Sprache entfernt wurde. Verwenden Sie stattdessen For-In-Schleifen. Swift verfolgt den Index intern.
Donarb

1
Das würde nicht so funktionieren. Sie müssen zuerst die Summe auf 0 initialisieren. Das Schöne an Reduzieren ist, dass es Sie daran erinnert, an den Anfangswert zu denken.
MarkAurelius

var sum = 0 ; for n in multiples { sum += n }obwohl ich reduzieren würde.
JeremyP

2

Eine mögliche Lösung: Definieren Sie einen Präfixoperator dafür. Wie der Reduzierungsoperator "+ /" wie in APL (zB GNU APL)

Ein etwas anderer Ansatz hier.

Die Verwendung eines generischen Protokolltyps ermöglicht es uns, diesen Operator für Double-, Float- und Int-Array-Typen zu verwenden

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
   }
}

Verwenden Sie wie folgt:

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

(aktualisiert für Swift 2.2, getestet in Xcode Version 7.3)


Ein Problem dabei ist, dass Sie häufig (zumindest bei großen Arrays) die Summe benötigen, um einen anderen Typ als die Komponenten zu haben. Wenn Sie beispielsweise eine Million UInt32s haben, die den Farbumfang von 0 bis 2 ^ 32-1 ausführen (z. B. mit arc4random () gefüllt), wird Ihr UInt32-Summenwert jedes Mal überfüllt, wenn Sie diese addieren.
Tom Dibble

2

Swift 3.0

Ich hatte das gleiche Problem, ich fand in der Dokumentation Apple diese Lösung.

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

Aber in meinem Fall hatte ich eine Liste von Objekten, dann musste ich meinen Wert meiner Liste transformieren:

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

diese Arbeit für mich.


0
@IBOutlet var valueSource: [MultipleIntBoundSource]!

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

hat diesen für verschachtelte Parameter verwendet


0

Halte es einfach...

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)")

Ausgabe:

Meine Summe der Elemente ist: 37


0

Für mich war es so, wenn ich Eigentum benutzte

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

-2

Swift 3

Von allen hier angezeigten Optionen hat diese für mich funktioniert.

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


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

Dies ist nur eine Kopie einer anderen Antwort
Ashley Mills

-2

Für die Summe der Elemente in einem Array von Objekten

self.rankDataModelArray.flatMap{$0.count}.reduce(0, +)

-4

Das ist mein Ansatz dazu. Ich glaube jedoch, dass die beste Lösung die Antwort des Benutzernamens tbd ist

var i = 0 
var sum = 0
let example = 0
for elements in multiples{
    i = i + 1
    sum = multiples[ (i- 1)]
    example = sum + example
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.