Search code examples
swiftswift5

Generating a continuous alphabetical list (from a-z then from aa, bb, cc, ..., aaa, bbb, ccc)


I have found a similar solution in Python, but I'm not too experienced with itertools to replicate it in SwiftUI.

However, I'm not looking for a...z, aa, ab, ac...

I'm looking to generate (based on a number) the following:

a...z, aa, bb, cc, dd..., aaa, bbb, ccc, ddd

I've tried adding every used label to an array, and if it exists, I will just add another letter.

Is this bad practice? I can't find any other solutions online, and racked my brain to come up with even this simple solution.

I would love a simple generator that doesn't have to modify a state array variable, since I might need to generate hundreds and want to keep this somewhat unimportant design style from slowing my app down.

Any help is appreciated, thanks so much

UPDATE: I've come up with another solution, but wouldn't mind a better one:

func nextAlphabeticalLabel(list_index: Int) -> String {
    let characterset = Array("abcdefghijklmnopqrstuvwxyz")
    var char = ""
    
    if list_index < characterset.count {
        char = "\(characterset[list_index])"
        
        return char
    }
    
    var absolute_char_index = list_index
    var times = 1
    
    while absolute_char_index > 25 {
        absolute_char_index -= 26
        times += 1
    }
    
    return String(repeating: characterset[absolute_char_index], count: times)
}

Solution

  • If you import Algorithms you can use product

    let p = product(1...,  UnicodeScalar("a").value...UnicodeScalar("z").value)
        .lazy
        .map { (i, v) -> String in
            String(repeating: String(UnicodeScalar(v)!), count: i)
        }
    

    That will give you a lazy map sequence, e.g. take the first 1000 items:

    for t in p.prefix(1000) {
        print(t)
    }
    

    Or perhaps you want to make an iterator like:

        var i = p.makeIterator()
    

    and then use it to generate the next value with

        i.next()