Tìm tổng các phần tử trong mảng Swift


228

Cách dễ nhất (tốt nhất) để tìm tổng của một mảng các số nguyên trong swift là gì? Tôi có một mảng được gọi là bội số và tôi muốn biết tổng của bội số.

Câu trả lời:


466

Đây là phương pháp dễ nhất / ngắn nhất tôi có thể tìm thấy.

Swift 3 và Swift 4:

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

Swift 2:

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

Một số thông tin thêm:

Phương pháp này sử dụng phương thức rút gọn của Array (tài liệu ở đây ), cho phép bạn "giảm tập hợp các phần tử xuống một giá trị bằng cách áp dụng đệ quy bao đóng được cung cấp". Chúng tôi cho nó 0 làm giá trị ban đầu, và sau đó, về cơ bản, đóng { $0 + $1 }. Tất nhiên, chúng ta có thể đơn giản hóa điều đó thành một dấu cộng duy nhất, vì đó là cách Swift cuộn.


42
Cảm ơn câu trả lời này. Nó hoạt động rất tốt và tôi chỉ muốn thêm mã ví dụ của mình với một loạt các lớp tùy chỉnh:let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal

2
Câu trả lời tuyệt vời nhưng thiếu tên tham số combine. Nên multiples.reduce(0, combine: +).
Evgenii

2
Có nhanh hơn vòng lặp for không?
lorenzo

1
@SwiftMatt Hãy thử sử dụng một flatMaptrên nó trước để làm phẳng nó thành một mảng kích thước duy nhất. multiArray.flatMap{$0}.reduce(0, combine: +)
Samah

2
@lorenzo - Thử nghiệm trên iPhone 7 bằng Swift và XCode mới nhất (một mảng đơn giản chứa 1.000.000 giá trị ngẫu nhiên UInt32 được giới hạn ở mức 256 để ngăn tràn UInt32) thú vị cho thấy vòng lặp 'for' chỉ là một sợi tóc nhanh hơn (1.941 giây so với 2.137 giây) , mặc dù lợi thế đó không có ở 100.000 giá trị (mỗi giá trị 0,23 giây). IMHO, độ rõ của mã có giá trị bất kỳ chi phí hiệu năng rất nhỏ nào ở đây ngay cả khi xử lý các mảng 32 MB.
Tom Dibble

84

Swift 3+ một lớp lót để tính tổng các thuộc tính của các đối tượng

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

Trong đó điểm là thuộc tính trong thang đo đối tượng tùy chỉnh của tôi mà tôi đang cố gắng giảm



22

Trong Swift 4 Bạn cũng có thể hạn chế các yếu tố tự để Numeric giao thức để trả lại tổng của tất cả các yếu tố trong chuỗi như sau

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

chỉnh sửa / cập nhật:

Xcode 10.2 • Swift 5 trở lên

Chúng ta có thể chỉ cần giới hạn các phần tử chuỗi thành giao thức AdditiveArithatures mới để trả về tổng của tất cả các phần tử trong bộ sưu tập

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

Xcode 11 • Swift 5.1 trở lên

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
Tuyệt vời, giải pháp tốt đẹp!
Sontand

11

Điều này cũng hoạt động:

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

Kết quả sẽ là: 55


10

Ví dụ Swift

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

Nếu bạn có một mảng các đối tượng chung và bạn muốn tính tổng một số thuộc tính đối tượng thì:

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 

Mặc dù hình thức ngắn hơn, nhiều lần bạn có thể thích chu kỳ cổ điển:

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, đây là giải pháp của tôi: mảng.map ({$ 0.value}). giảm (0, +)
Ivailo Kanev

Theo cách này, bạn viết thêm mã và tăng độ phức tạp .. vậy, tại sao?
Luca Davanzo

6

Cách đơn giản

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

// trong đó n = số phần tử trong mảng


Lưu ý rằng trong Swift 3, điều này không còn hợp lệ vì kiểu C cho các vòng lặp đã bị xóa khỏi ngôn ngữ. Thay vào đó, sử dụng các vòng lặp for-in, Swift theo dõi nội bộ của chỉ mục.
donarb

1
Điều đó sẽ không làm việc như nó. Bạn phải khởi tạo tổng thành 0 trước. Vẻ đẹp của giảm là nó nhắc nhở bạn nghĩ về giá trị ban đầu.
MarkAurelius

var sum = 0 ; for n in multiples { sum += n }mặc dù tôi sẽ sử dụng giảm.
JeremyP

2

Một giải pháp có thể: xác định một toán tử tiền tố cho nó. Giống như toán tử giảm "+ /" như trong APL (ví dụ: GNU APL)

Một chút của một cách tiếp cận khác nhau ở đây.

Sử dụng một giao thức kiểu chung cho phép chúng ta sử dụng toán tử này trên các kiểu mảng Double, Float và 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
   }
}

sử dụng như vậy:

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

(được cập nhật cho Swift 2.2, được thử nghiệm trong Xcode Phiên bản 7.3)


Một vấn đề với điều này là thường (ít nhất, khi xử lý các mảng lớn), bạn sẽ cần tổng là một loại khác với các thành phần. Chẳng hạn, nếu bạn có một triệu UInt32 chạy gam từ 0 đến 2 ^ 32-1 (ví dụ, được điền bởi arc4random ()), việc thêm chúng sẽ tràn giá trị "tổng" UInt32 của bạn mỗi lần.
Tom Dibble

2

Swift 3.0

Tôi đã có cùng một vấn đề, tôi tìm thấy trên tài liệu Apple giải pháp này.

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

Nhưng, trong trường hợp của tôi, tôi đã có một danh sách các đối tượng, sau đó tôi cần chuyển đổi giá trị của danh sách của mình:

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

công việc này cho tôi


0
@IBOutlet var valueSource: [MultipleIntBoundSource]!

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

đã sử dụng cái này cho các tham số lồng nhau


0

Giữ cho nó đơn giản ...

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

Đầu ra:

Tổng các yếu tố của tôi là: 37


0

Đối với tôi, nó là như thế này bằng cách sử dụng tài sản

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

-2

Swift 3

Từ tất cả các tùy chọn hiển thị ở đây, đây là tùy chọn phù hợp với tôi.

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


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

Đây chỉ là một bản sao của một câu trả lời khác
Ashley Mills

-2

Để tính tổng các phần tử trong mảng Đối tượng

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

-4

đây là cách tiếp cận của tôi về điều này tuy nhiên tôi tin rằng giải pháp tốt nhất là câu trả lời từ tên người dùng tbd

var i = 0 
var sum = 0
let example = 0
for elements in multiples{
    i = i + 1
    sum = multiples[ (i- 1)]
    example = sum + example
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.