Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift, can I write a generic function to resize an array?

Tags:

swift

I have this function:

func sizeArray(inout array:Array<String>, size:Int) {

    while (array.count < size) {
        array.append("")
    }

    while (array.count > size) {
        array.removeLast()
    }
}

It works, but only with Array of String, can I make it generic to work with any type?

like image 307
Roland Rabien Avatar asked Sep 07 '25 20:09

Roland Rabien


1 Answers

The most generic method...

  1. Array adapts RangeReplaceableCollection protocol which include methods which can help resizing. (No need to use a loop)

  2. You need to construct new instances of the element when you grow the array. So you either provide a default value...

extension RangeReplaceableCollection {
    public mutating func resize(_ size: IndexDistance, fillWith value: Iterator.Element) {
        let c = count
        if c < size {
            append(contentsOf: repeatElement(value, count: c.distance(to: size)))
        } else if c > size {
            let newEnd = index(startIndex, offsetBy: size)
            removeSubrange(newEnd ..< endIndex)
        }
    }
}

var f = ["a", "b"]
f.resize(5, fillWith: "")    // ["a", "b", "", "", ""]
f.resize(1, fillWith: "")    // ["a"]
  1. or you create a protocol that provides the default value init(). Note that you need to manually adapt the protocol to every types you care about.
public protocol DefaultConstructible {
    init()
}

extension String: DefaultConstructible {}
extension Int: DefaultConstructible {}
// and so on...

extension RangeReplaceableCollection where Iterator.Element: DefaultConstructible {
    public mutating func resize(_ size: IndexDistance) {
        resize(size, fillWith: Iterator.Element())
    }
}

var g = ["a", "b"]
g.resize(5)
g.resize(1)
like image 98
kennytm Avatar answered Sep 09 '25 19:09

kennytm