2

Swift has a great function .reduce that provides a running total for an entire array:

let array = [1, 2, 3, 4, 5]
let addResult = array.reduce(0) { $0 + $1 }
// addResult is 15

let multiplyResult = array.reduce(1) { $0 * $1 }
// multiplyResult is 120

But is there a simple way to use this for a running total only up to a specific element? For example for an array of [1, 2, 3, 4, 5] is there a way to use the .reduce function to return a running total for only up to the 3rd item (1+2+3=6)?

(I know I can always do a loop, just trying to learn all the possibilities with swift)

2 Answers 2

2

Besides using the reduce method of arrays, as in @MartinR's answer, it's also possible to use the global reduce function along with enumerate

The enumerate function returns a sequence of tuples, whose first element (named index) is the element index and the second (named element) is the element value.

So you can achieve the same result with the following code:

let sum = reduce(enumerate(array), 0) {
    $0 + ($1.index < 3 ? $1.element : 0)
}

The advantage of this method is that you can apply more complex rules to exclude elements - for example, to sum all elements having even index:

let sum = reduce(enumerate(array), 0) {
    $0 + ($1.index % 2 == 0 ? $1.element : 0)
}
Sign up to request clarification or add additional context in comments.

Comments

1

The closure called by reduce() has no information about the current index. Theoretically it is possible to create a closure that uses a captured variable to "remember" how often it has been called:

func addFirst(var count : Int) -> (Int, Int) -> Int {
    return {
        count-- > 0 ? $0 + $1 : $0
    }
}

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array.reduce(0, addFirst(3) )

But this would still run over the whole array and not just the first 3 elements. There is no way to "stop" the process.

A much simpler way is to operate on an array slice:

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array[0 ..< 3].reduce(0) { $0 + $1 }

A slice is an Array-like type that represents a sub-sequence of any Array, ContiguousArray, or other Slice.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.