스위프트 배열에서 요소의 합 찾기


228

신속하게 정수 배열의 합계를 찾는 가장 쉬운 방법은 무엇입니까? 배수라는 배열이 있고 배수의 합을 알고 싶습니다.

답변:


466

이것은 내가 찾을 수있는 가장 쉬운 방법입니다.

스위프트 3과 스위프트 4 :

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

스위프트 2 :

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

더 많은 정보 :

여기에는 Array의 reduce 메소드 (documentation here )를 사용하여 "제공된 클로저를 재귀 적으로 적용하여 요소 컬렉션을 단일 값으로 줄일 수 있습니다". 초기 값으로 0을 부여한 다음 본질적으로 클로저를 제공 { $0 + $1 }합니다. 물론 Swift가 롤링하는 방식이기 때문에 단일 더하기 부호로 단순화 할 수 있습니다.


42
이 답변에 감사드립니다. 훌륭하게 작동하며 사용자 정의 클래스 배열로 예제 코드를 추가하고 싶습니다.let totalSum = self.cheques.reduce(0) { $0 + $1.amount}
Libor Zapletal

2
훌륭한 답변이지만 매개 변수 이름이 없습니다 combine. 이어야 multiples.reduce(0, combine: +)합니다.
Evgenii

2
for 루프보다 빠릅니까?
lorenzo

1
@SwiftMatt flatMap먼저 그것을 사용하여 단일 차원 배열로 평면화하십시오. multiArray.flatMap{$0}.reduce(0, combine: +)
Samah

2
@lorenzo-최신 Swift 및 XCode (UInt32 오버플로를 방지하기 위해 256에서 1,000,000 개의 UInt32 임의 값으로 채워진 간단한 배열)로 iPhone 7에서 테스트하면 'for'루프가 머리카락이 더 빠릅니다 (1.941 초 대 2.137 초) 이 장점은 100,000 값 (각 0.23 초)으로 나타나지 않습니다 . IMHO, 코드 선명도는 32MB 어레이를 다룰 때에도 약간의 성능 비용이 필요합니다.
Tom Dibble

84

스위프트 3+ 하나의 라이너로 객체의 속성을 합산

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

어디 포인트 내 사용자 정의 개체의 속성입니다 scaleData 내가 줄이기 위해 노력하고 있음은


28

Swift3가 다음으로 변경되었습니다.

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

22

에서 스위프트 4 당신은 또한에 시퀀스 요소를 제한 할 수 숫자의 다음과 같은 순서로 모든 요소의 합을 반환하는 프로토콜을

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

편집 / 업데이트 :

Xcode 10.2 • 스위프트 5 이상

시퀀스 요소를 새로운 AdditiveArithmetic 프로토콜로 제한 하여 컬렉션의 모든 요소의 합을 반환 할 수 있습니다.

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

Xcode 11 • 스위프트 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
훌륭하고 좋은 해결책!
sabiland

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

스위프트 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 

짧은 형식에도 불구하고 여러 번 고전적인주기를 선호 할 수 있습니다.

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}) (0, +) 줄일 수 있습니다.
이바 일로 Kanev

이런 식으로 더 많은 코드를 작성하고 복잡성을 증가시킵니다. 왜 그렇습니까?
Luca Davanzo

6

간단한 방법은 어떻습니까

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

// 여기서 n = 배열의 요소 수


Swift 3에서는 C 스타일 for 루프가 언어에서 제거되었으므로 더 이상 유효하지 않습니다. 대신 for-in 루프를 사용하면 Swift는 인덱스의 내부를 추적합니다.
donarb

1
그것은 작동하지 않을 것입니다. 먼저 합계를 0으로 초기화해야합니다. 감소의 장점은 초기 값을 생각 나게한다는 것입니다.
MarkAurelius

var sum = 0 ; for n in multiples { sum += n }비록 내가 reduce를 사용할 것이지만.
JeremyP

2

가능한 해결책 : 접두사 연산자를 정의하십시오. APL에서와 같이 "+ /"축소 연산자처럼 (예 : GNU APL)

여기에 약간 다른 접근 방식이 있습니다.

프로토콜 en 제네릭 형식을 사용하면 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

(Xcode 버전 7.3에서 테스트 된 Swift 2.2 용으로 업데이트 됨)


이것의 한 가지 문제는 종종 (적어도 큰 배열을 다룰 때) 합계가 구성 요소와 다른 유형이어야한다는 것입니다. 예를 들어, 0에서 2 ^ 32-1 (예 : arc4random ()로 채워짐) 범위를 실행하는 UInt32가 수백만 개에 달할 때마다 UInt32 "sum"값을 초과 할 때마다 오버 플로우됩니다.
Tom Dibble

2

스위프트 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)

이것은 또 다른 답변의 사본 일뿐입니다
Ashley Mills


-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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.