22

I'm working with a struct which has an array. I would like to add a new element to the array, however, the array is immutable so I can't simply append to it. Need to create a new array, append to it and then create a new structure with the extended array. (I know it sounds painful and memory intensive, but it is cleaner and more aligned with the Functional Programming paradigm.)

Is there an append() like function that doesn't mutate the array but instead returns a new one? This would be easier than having to declare a new array and appending to it.

4 Answers 4

45

Would you not just add two arrays together?

let originalArray: [Type] = ...
let objectToAppend: Type = ...
let newArray = originalArray + [objectToAppend]


Or, in an extension, if you prefer:

extension Array {
    func arrayByAppending(o: Element) -> [Element] {
        return self + [o]
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Small micro optimization could be to use self + CollectionOfOne(o)
1

Try this:

extension NSArray {
    func myAppend(arrToAppend: NSArray) -> NSArray {
        let r : NSMutableArray = NSMutableArray(array: self)
        r.addObjectsFromArray(arrToAppend as [AnyObject])
        return r.copy() as! NSArray
    }
}

for a single object

extension NSArray {
    func myAppend2(objToAppend: AnyObject) -> NSArray {
        let r : NSMutableArray = NSMutableArray(array: self)
        r.addObject(objToAppend)
        return r.copy() as! NSArray
    }
}

1 Comment

Thanks. But I just want to add an element. (Not an array)
1

Try like this:

extension Array {
    func appendToNewArray(newElement: Element) -> Array {
        var result = self
        result.append(newElement)
        return result
    }
}

let ar = [1,2]

let ar2 = ar.appendToNewArray(3)
print(ar2)   // "[1, 2, 3]\n"

Comments

1

This is a common issue, you wish to create a new modified value, but you don't what that mutability to "leak" out. This can be solved by creating a small function which does exactly that:

func withMutator<T>(_ value: T, mutator: (inout T) -> Void) -> T {
    var value = value
    mutator(&value)
    return value
}

Use it directly (using Max's naming):

let newArray = withMutator(originalArray) { $0.append(objectToAppend) }

Alternatively, as others have shown in their answers, extend Array:

extension Array {
    func arrayByAppending(_ newElement: Element) -> Array<Element> {
        return withMutator(self) { $0.append(newElement) }
    }
}

let newArray = originalArray.arrayByAppending(objectToAppend)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.