Recherche de la somme des éléments dans le tableau Swift

229

Quelle est la façon la plus simple (la meilleure) de trouver la somme d'un tableau d'entiers dans swift? J'ai un tableau appelé multiples et je voudrais connaître la somme des multiples.

ejLev
la source

Réponses:

466

C'est la méthode la plus simple / la plus courte que je puisse trouver.

Swift 3 et Swift 4:

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

Swift 2:

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

Quelques informations supplémentaires:

Cela utilise la méthode de réduction d'Array (documentation ici ), qui vous permet de "réduire une collection d'éléments à une seule valeur en appliquant récursivement la fermeture fournie". Nous lui donnons 0 comme valeur initiale, puis, essentiellement, la fermeture { $0 + $1 }. Bien sûr, nous pouvons simplifier cela en un seul signe plus, car c'est ainsi que Swift roule.

nom d'utilisateur tbd
la source
42
Merci pour cette réponse. Cela fonctionne très bien et je veux juste ajouter mon exemple de code avec un tableau de classes personnalisées:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal
2
Grande réponse mais nom de paramètre manquant combine. Devrait l'être multiples.reduce(0, combine: +).
Evgenii
2
Est-ce plus rapide qu'une boucle for?
lorenzo
1
@SwiftMatt Essayez d'abord d'utiliser un flatMapdessus pour l'aplatir en un tableau à une dimension. multiArray.flatMap{$0}.reduce(0, combine: +)
Samah
2
@lorenzo - Les tests sur un iPhone 7 avec les dernières Swift et XCode (un tableau simple rempli de 1000000 valeurs aléatoires UInt32 plafonnées à 256 pour éviter le débordement d'UInt32) montrent de manière intéressante que la boucle `` pour '' n'est qu'un cheveu plus rapide (1,941 secondes contre 2,137 secondes) , bien que cet avantage ne soit pas présent à 100 000 valeurs (0,23 seconde chacune). À mon humble avis, la clarté du code vaut tout coût de performance très mineur ici même lorsqu'il s'agit de tableaux de 32 Mo.
Tom Dibble
85

Swift 3+ one liner pour additionner les propriétés des objets

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

Où les points sont la propriété dans mon échelle d' objet personnalisé Données que j'essaie de réduire

Jesus Rodriguez
la source
28

Swift3 est devenu:

let multiples = [...]
sum = multiples.reduce(0, +)
developermike
la source
22

Dans Swift 4, vous pouvez également contraindre les éléments de séquence au protocole numérique pour renvoyer la somme de tous les éléments de la séquence comme suit

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

éditer / mettre à jour:

Xcode 10.2 • Swift 5 ou version ultérieure

Nous pouvons simplement contraindre les éléments de séquence au nouveau protocole AdditiveArithmetic pour renvoyer la somme de tous les éléments de la collection

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

Xcode 11 • Swift 5.1 ou version ultérieure

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
la source
1
Grande, belle solution!
sabiland
11

Cela fonctionne également:

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

Le résultat sera de: 55

Marco Almeida
la source
10

Exemple 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
Maciej
la source
9

Swift 3

Si vous avez un tableau d'objets génériques et que vous souhaitez additionner une propriété d'objet, alors:

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 

Malgré la forme plus courte, vous préférerez souvent le classique pour le 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
la source
1
ciao Luca, voici ma solution: array.map ({$ 0.value}). réduire (0, +)
Ivailo Kanev
De cette façon, vous écrivez plus de code et augmentez la complexité .. alors, pourquoi?
Luca Davanzo
6

Que diriez-vous de la manière simple de

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

// où n = nombre d'éléments dans le tableau

Naishta
la source
Notez que dans Swift 3, cela n'est plus valide car le style C pour les boucles a été supprimé du langage. Utilisez plutôt des boucles for-in, Swift assure le suivi en interne de l'index.
donarb
1
Cela ne fonctionnerait pas comme ça. Vous devez d'abord initialiser sum à 0. La beauté de réduire est qu'il vous rappelle de penser à la valeur initiale.
MarkAurelius
var sum = 0 ; for n in multiples { sum += n }même si j'utiliserais réduire.
JeremyP
2

Une solution possible: définir un opérateur de préfixe pour cela. Comme l'opérateur de réduction "+ /" comme dans APL (par exemple GNU APL)

Un peu d'une approche différente ici.

L'utilisation d'un protocole de type générique nous permet d'utiliser cet opérateur sur les types de tableaux Double, Float et 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
   }
}

utiliser comme ça:

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

(mis à jour pour Swift 2.2, testé dans Xcode version 7.3)

Ted van Gaalen
la source
Un problème avec cela est que souvent (au moins, lorsqu'il s'agit de grands tableaux), vous aurez besoin que la somme soit d'un type différent de celui des composants. Par exemple, si vous avez un million d'UInt32 exécutant la gamme de 0 à 2 ^ 32-1 (ex, remplie par arc4random ()), l'ajout de ceux-ci débordera à chaque fois votre valeur "somme" UInt32.
Tom Dibble
2

Swift 3.0

j'ai eu le même problème, j'ai trouvé sur la documentation Apple cette solution.

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

Mais, dans mon cas, j'avais une liste d'objets, alors j'avais besoin de transformer ma valeur de ma liste:

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

ce travail pour moi.

Luan Almeida
la source
0
@IBOutlet var valueSource: [MultipleIntBoundSource]!

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

utilisé celui-ci pour les paramètres imbriqués

Alexey Lysenko
la source
0

Rester simple...

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

Production:

Ma somme d'éléments est: 37

Israel Manzo
la source
0

Pour moi, c'était comme ça en utilisant la propriété

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

Swift 3

De toutes les options affichées ici, c'est celle qui a fonctionné pour moi.

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


var sumedArr = arr.reduce(0, { ($0 + $1)})
print(sumedArr)
Victor
la source
Ceci est juste une copie d'une autre réponse
Ashley Mills
-2

Pour la somme des éléments dans un tableau d'objets

self.rankDataModelArray.flatMap{$0.count}.reduce(0, +)
Manish Mahajan
la source
-4

c'est mon approche à ce sujet. mais je pense que la meilleure solution est la réponse du nom d' utilisateur tbd

var i = 0 
var sum = 0
let example = 0
for elements in multiples{
    i = i + 1
    sum = multiples[ (i- 1)]
    example = sum + example
}
user3413044
la source