Нахождение суммы элементов в массиве Swift

229

Какой самый простой (лучший) способ найти сумму массива целых чисел в swift? У меня есть массив с именем кратных, и я хотел бы знать сумму кратных.

ejLev
источник

Ответы:

467

Это самый простой / самый короткий метод, который я могу найти.

Свифт 3 и Свифт 4:

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

Свифт 2:

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

Еще немного информации:

При этом используется метод снижения массива (документация здесь ), который позволяет «уменьшить коллекцию элементов до одного значения путем рекурсивного применения предоставленного замыкания». Мы даем ему 0 в качестве начального значения, а затем, по сути, замыкание { $0 + $1 }. Конечно, мы можем упростить это до единого знака плюс, потому что так крутится Swift.

имя пользователя
источник
42
Спасибо за этот ответ. Это прекрасно работает, и я просто хочу добавить свой пример кода с массивом пользовательских классов:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal
2
Отличный ответ, но отсутствует имя параметра combine . Должно быть multiples.reduce(0, combine: +).
Евгений
2
Это быстрее, чем для цикла?
Лоренцо
1
@SwiftMatt Попробуйте сначала использовать flatMapего, чтобы сгладить его в одном массиве измерений.multiArray.flatMap{$0}.reduce(0, combine: +)
Сама
2
@lorenzo - Тестирование на iPhone 7 с последними версиями Swift и XCode (простой массив, заполненный 1 000 000 случайных значений UInt32, ограниченных 256 для предотвращения переполнения UInt32), интересно показывает, что цикл for является всего лишь на волосок быстрее (1,941 секунды против 2,137 секунды) , хотя это преимущество заключается в том, не присутствует на 100000 значений (0,23 секунд каждый). ИМХО, ясность кода здесь стоит очень незначительных затрат на производительность, даже при работе с массивами 32 МБ.
Том Диббл
85

Swift 3+ один лайнер для суммирования свойств объектов

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

куда точки - это свойство в моем пользовательском объекте scaleData, которое я пытаюсь уменьшить

Хесус Родригес
источник
28

Swift3 изменился на:

let multiples = [...]
sum = multiples.reduce(0, +)
developermike
источник
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
Чао Лука, вот мое решение: array.map ({$ 0.value}). Reduce (0, +)
Ивайло Канев
Таким образом, вы пишете больше кода и увеличиваете сложность .. так почему?
Лука Даванзо
6

Как насчет простого способа

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

// где n = количество элементов в массиве

Naishta
источник
Обратите внимание, что в Swift 3 это больше не действует, потому что стиль C для циклов был удален из языка. Вместо этого используйте циклы for-in, Swift внутренне отслеживает индекс.
Донарб
1
Это не сработает. Вы должны инициализировать сумму до 0 в первую очередь. Прелесть снижения заключается в том, что он напоминает вам о первоначальной ценности.
Марк Аврелий,
var sum = 0 ; for n in multiples { sum += n }хотя я бы использовал уменьшить.
JeremyP
2

Возможное решение: определить для него префиксный оператор. Как и оператор «+ /» уменьшения, как в APL (например, GNU APL)

Здесь немного другой подход.

Использование протокола общего типа позволяет нам использовать этот оператор в массивах типа 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)

Тед ван Гаален
источник
Одна из проблем заключается в том, что часто (по крайней мере, при работе с большими массивами) вам понадобится сумма, отличная от компонентов. Например, если у вас есть миллион UInt32, использующих гамму от 0 до 2 ^ 32-1 (например, заполненных arc4random ()), их добавление будет переполнять ваше значение sum для 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)
Виктор
источник
Это всего лишь копия другого ответа
Эшли Миллс
-2

Для суммы элементов в массиве объектов

self.rankDataModelArray.flatMap{$0.count}.reduce(0, +)
Маниш Махаджан
источник
-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
}
user3413044
источник