Exercism v3 launches on Sept 1st 2021. Learn more! ๐Ÿš€๐Ÿš€๐Ÿš€
Avatar of griffin-stewie

griffin-stewie's solution

to Accumulate in the Swift Track

Published at May 05 2021 · 0 comments
Test suite

Implement the accumulate operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.

Given the collection of numbers:

  • 1, 2, 3, 4, 5

And the operation:

  • square a number (x => x * x)

Your code should be able to produce the collection of squares:

  • 1, 4, 9, 16, 25

Check out the test suite to see the expected function signature.


Keep your hands off that collect/map/fmap/whatchamacallit functionality provided by your standard library! Solve this one yourself using other basic tools instead.


Go through the project setup instructions for Xcode using Swift:


Notably from the source directory:

swift test runs tests
swift package generate-xcodeproj creates an Xcode project


Conversation with James Edward Gray II https://twitter.com/jeg2

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.


import XCTest
@testable import Accumulate

private extension String {
    var length: Int { return self.count }

    func reverse() -> String {
        var result: String = ""
        for char in self {
            result = "\(char)\(result)"
        return result

private extension XCTest {
    func XCTAssertEqualMultiArray(_ aArray1: [[String]], _ aArray2: [[String]]) {
        XCTAssertEqual(Array(aArray1.joined()), Array(aArray2.joined()))

class AccumulateTests: XCTestCase {
    func testEmptyAccumulation() {
        let input = [Int]()
        func square(_ input: Int) -> Int {
            return input * input
        let result = input.accumulate(square)


    func testAccumulateSquares() {
        let input = [1, 2, 3, 4]
        let expected = [1, 4, 9, 16]
        func square(_ input: Int) -> Int {
            return input * input
        let result = input.accumulate(square)

        XCTAssertEqual(expected, result)

    func testAccumulateUpcases() {
        let input = ["hello", "world"]
        let expected = ["HELLO", "WORLD"]
        func toUpper(_ input: String) -> String {
            return input.uppercased()
        let result = input.accumulate(toUpper)

        XCTAssertEqual(expected, result)


    func testAccumulateReversedStrings() {
        let input =    ["the", "quick", "brown", "fox", "etc"]
        let expected = ["eht", "kciuq", "nworb", "xof", "cte"]
        func reverse(_ input: String) -> String {
            return input.reverse()
        let result = input.accumulate(reverse)

        XCTAssertEqual(expected, result)

    func testAccumulateRecursively() {
        let input =   ["a", "b", "c"]
        let expected = [
            ["a1", "a2", "a3"],
            ["b1", "b2", "b3"],
            ["c1", "c2", "c3"]
        func recurse(_ input: String) -> [String] {
            func appendTo(_ innerInput: String) -> String {
                return input+innerInput
            let result = ["1", "2", "3"].accumulate(appendTo)
            return result
        let result = input.accumulate(recurse)

        XCTAssertEqualMultiArray(expected, result)

    static var allTests: [(String, (AccumulateTests) -> () throws -> Void)] {
        return [
            ("testEmptyAccumulation", testEmptyAccumulation),
            ("testAccumulateSquares", testAccumulateSquares),
            ("testAccumulateUpcases", testAccumulateUpcases),
            ("testAccumulateReversedStrings", testAccumulateReversedStrings),
            ("testAccumulateRecursively", testAccumulateRecursively),


import XCTest
@testable import AccumulateTests

//Solution goes in Sources
extension Collection {
    func accumulate<T>(_ closure: (Element) -> T) -> [T] {
        var store: [T] = []
        for v in self {
        return store

What can you learn from this solution?

A huge amount can be learned from reading other peopleโ€™s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?