Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Given an unique string that represents a sequence of characters, the class should implement three methods (getNextChar, getNextString and the genSequence generator).

How it works

  1. We give a sequence of characters. For example: "abc"
  2. We give a starting string. For example: "a"
  3. The generator yields the following strings infinitely.

The next string of an existing string works like a dictionary, only the length doesn't change as long as there are still characters to fulfill.

a
b
c
aa
ab
ac
ba
..
cc
aaa
aab

This is not homework, but a user in Stack Overflow chat presented the challenge and I considered taking it to a higher level.

class SeqString {

    constructor (sequence) {

        this._sequence = sequence;
        this._first    = sequence[0];
        this._last     = sequence.slice(-1);

        return this;
    }

    getNextChar (char) {

        let seq   = this._sequence,
            index = (seq.indexOf(char) + 1) % seq.length;

        return seq[index];
    }

    getNextString (str) {

        let last = str.slice(-1),
            init = str.slice(0, str.length - 1),

            lastOfSeq  = this._last,
            firstOfSeq = this._first;

        // If it is overflowing
        if (last === lastOfSeq) {

            let trail = 1,
                i     = init.length;

            // Look for an index that won't overflow
            while (i-- && init[i] === lastOfSeq) ++trail;

            // If there is no such index, then the result is a new sequence
            // with an increased length
            if (i === -1) return firstOfSeq.repeat(trail + 1);

            // If there is, change the matching character at the index
            // and reset every character after that
            str = init.slice(0, i) + this.getNextChar(init[i]) +
                  firstOfSeq.repeat(trail);

            return str;

        }

        return init + this.getNextChar(last);
    }

    *genSequence (str) {

        let newStr = this.getNextString(str);

        yield newStr;
        yield* this.genSequence(newStr);    
    }

}

Specific questions

  • How can I improve my class functions, while maintaining a balance between performance and readability?
  • Tips on how I could make the code more readable for others.

Test cases

I have made a function test, to help debugging.

function test (sequence, startStr, times = 10) {

    let it = new SeqString(sequence).genSequence(startStr);

    while (times--)
        console.log(it.next().value);
}

Examples of output

Alphaset tests

const lowerAlpha = "abcdefghijklmnopqrstuvwxyz";
const alpha      = lowerAlpha + lowerAlpha.toUpperCase();

test(alpha, 'abc', 1); // abd 
test(alpha, 'BZZ', 1); // Caa
test(alpha, 'Z', 1); // aa 
test(alpha, 'ZZ', 1); // aaa

A long sequence for test(alpha, "Stack"): http://lpaste.net/137336

Other tests

test("pen", "p", 10);

e
n
pp
..
np

test("0123456789", "5", 10);

6
7
8
9
00
01
02
..

It should

  • Use ES6 features
  • Expose a generator
  • Handle every kind of unique sequence
  • Be readable
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.