DanielZanchi
DanielZanchi

Reputation: 2768

How to increment String in Swift

I need to save files in an alphabetical order.
Now my code is saving files in numeric order

1.png
2.png
3.png
...

The problem is when i read this files again I read this files as described here


So I was thinking of changing the code and to save the files not in a numeric order but in an alphabetical order as:

a.png
b.png
c.png
...
z.png
aa.png
ab.png
...

But in Swift it's difficult to increment even Character type.
How can I start from:

var s: String = "a"

and increment s in that way?

Upvotes: 5

Views: 2845

Answers (3)

Milan V.
Milan V.

Reputation: 697

Paste this code in the playground and check result. n numbers supported means you can enter any high number such as 99999999999999 enjoy!

you can uncomment for loop code to check code is working fine or not but don't forget to assign a lesser value to counter variable otherwise Xcode will freeze.

var fileName:String = ""
var counter = 0.0
var alphabets = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
let totalAlphaBets = Double(alphabets.count)
let numFiles = 9999


func getCharacter(counter c:Double) -> String {

    var chars:String
    var divisionResult = Int(c / totalAlphaBets)
    let modResult = Int(c.truncatingRemainder(dividingBy: totalAlphaBets))

    chars = getCharFromArr(index: modResult)

    if(divisionResult != 0){

        divisionResult -= 1

        if(divisionResult > alphabets.count-1){
            chars = getCharacter(counter: Double(divisionResult)) + chars
        }else{
            chars = getCharFromArr(index: divisionResult) + chars
        }
    }

    return chars
}

func getCharFromArr(index i:Int) -> String {
    if(i < alphabets.count){
        return alphabets[i]
    }else{
        print("wrong index")
        return ""
    }
}

for _ in 0...numFiles {
    fileName = getCharacter(counter: counter)+".png"
    print(fileName)
    counter += 1
}

fileName = getCharacter(counter: Double(numFiles))+".png"
print(fileName)

Upvotes: 1

S&#248;ren Mortensen
S&#248;ren Mortensen

Reputation: 1755

If you'd really like to make them alphabetical, try this code to increment the names:

/// Increments a single `UInt32` scalar value
func incrementScalarValue(_ scalarValue: UInt32) -> String {
    return String(Character(UnicodeScalar(scalarValue + 1)))
}

/// Recursive function that increments a name
func incrementName(_ name: String) -> String {
    var previousName = name
    if let lastScalar = previousName.unicodeScalars.last {
        let lastChar = previousName.remove(at: previousName.index(before: previousName.endIndex))
        if lastChar == "z" {
            let newName = incrementName(previousName) + "a"
            return newName
        } else {
            let incrementedChar = incrementScalarValue(lastScalar.value)
            return previousName + incrementedChar
        }
    } else {
        return "a"
    }
}

var fileNames = ["a.png"]
for _ in 1...77 {
    // Strip off ".png" from the file name
    let previousFileName = fileNames.last!.components(separatedBy: ".png")[0]
    // Increment the name
    let incremented = incrementName(previousFileName)
    // Append it to the array with ".png" added again
    fileNames.append(incremented + ".png")
}

print(fileNames)
// Prints `["a.png", "b.png", "c.png", "d.png", "e.png", "f.png", "g.png", "h.png", "i.png", "j.png", "k.png", "l.png", "m.png", "n.png", "o.png", "p.png", "q.png", "r.png", "s.png", "t.png", "u.png", "v.png", "w.png", "x.png", "y.png", "z.png", "aa.png", "ab.png", "ac.png", "ad.png", "ae.png", "af.png", "ag.png", "ah.png", "ai.png", "aj.png", "ak.png", "al.png", "am.png", "an.png", "ao.png", "ap.png", "aq.png", "ar.png", "as.png", "at.png", "au.png", "av.png", "aw.png", "ax.png", "ay.png", "az.png", "ba.png", "bb.png", "bc.png", "bd.png", "be.png", "bf.png", "bg.png", "bh.png", "bi.png", "bj.png", "bk.png", "bl.png", "bm.png", "bn.png", "bo.png", "bp.png", "bq.png", "br.png", "bs.png", "bt.png", "bu.png", "bv.png", "bw.png", "bx.png", "by.png", "bz.png"]`

You will eventually end up with

a.png
b.png
c.png
...
z.png
aa.png
ab.png
...
zz.png
aaa.png
aab.png
...

Upvotes: 2

Code Different
Code Different

Reputation: 93171

You can keep it numeric, just use the right option when sorting:

let arr = ["1.png", "19.png", "2.png", "10.png"]

let result = arr.sort {
    $0.compare($1, options: .NumericSearch) == .OrderedAscending
}

// result: ["1.png", "2.png", "10.png", "19.png"]

Upvotes: 4

Related Questions