Array append() to return a new array
Asked Answered
W

4

20

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.

Walkon answered 26/5, 2016 at 6:25 Comment(0)
R
41

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]
    }
}
Roxannaroxanne answered 26/5, 2016 at 6:42 Comment(0)
R
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
    }
}
Rosado answered 26/5, 2016 at 6:40 Comment(1)
Thanks. But I just want to add an element. (Not an array)Walkon
T
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"
Tweeter answered 26/5, 2016 at 6:44 Comment(0)
S
0

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)
Shan answered 4/3, 2022 at 9:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.