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.

ejLev
quelle

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.

Benutzername tbd
quelle
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

Jesus Rodriguez
quelle
28

Swift3 hat sich geändert zu:

let multiples = [...]
sum = multiples.reduce(0, +)
entwicklungsähnlich
quelle
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
Leo Dabus
quelle
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

Marco Almeida
quelle
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
Maciej
quelle
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
}
Luca Davanzo
quelle
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

Naishta
quelle
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)

Ted van Gaalen
quelle
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.

Luan Almeida
quelle
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

Alexey Lysenko
quelle
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

Israel Manzo
quelle
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
    })
Ahmed Safadi
quelle
-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)
Sieger
quelle
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, +)
Manish Mahajan
quelle
-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
}
user3413044
quelle