6

I have an array consisting of A LOT of Symbol objects:

var symbols = {
    alpha : new Symbol('alpha', 'symbol_0', '&#x03B1', 'GreekSymbol'),
    beta : new Symbol('beta', 'symbol_1', '&#x03B2', 'GreekSymbol'),
    gamma : new Symbol('gamma', 'symbol_2', '&#x03B3', 'GreekSymbol'),
    delta : new Symbol('delta', 'symbol_3', '&#x03B4', 'GreekSymbol'),

    ... about 500 of these different types of symbols...
};

The second parameter for the Symbol object is an ID that will be used in HTML. Since the HTML specs don't allow duplicate IDs, I want to assign each Symbol a unique ID and still be able to know that this ID corresponds to a Symbol. So I like the idea of having the symbol_ prefix but I don't like the idea of manually typing out symbol_0 through symbol_500.

How should I generate unique IDs? Can I automate this process and generate a unique ID when I'm declaring the above array?

UPDATE
Is it actually a good idea to do this client-side?

Hristo
  • 45,559
  • 65
  • 163
  • 230

3 Answers3

9

Make a function that increments a counter:

function makeCounter() {
    var i = 0;
    return function() {
        return i++;
    }
}

var id = makeCounter();

Now each call to id will return a unique value:

id(); // 0
id(); // 1
id(); // 2
id(); // 3

Use it like this:

new Symbol('alpha', 'symbol_' + id(), '&#x03B1,', 'GreekSymbol')

A more fully-featured version would allow you to specify the prefix and an optional start value:

function generateId(prefix, start) {
    var i = start || 0;
    return function() {
        return prefix + i++;
    }
}
// start the counter at 12
var id = generateId("symbol_", 12);
id();

Output:

"symbol_12"
Wayne
  • 59,728
  • 15
  • 131
  • 126
  • Why wouldn't `makeCounter` return `1` everytime given you reset the value of `var i` each time you call the function ? – Sir Jan 17 '15 at 04:07
  • You only call `makeCounter` *once*. It happens here: `var id = makeCounter();`. After that, you call the function *returned* by `makeCounter`, which we've assigned to `id`. This function *closes over* the variable `i`, which means that each invocation is incrementing the same counter. – Wayne Jan 17 '15 at 05:02
1

A simple object that keeps track of the number of calls should work.

function IdGenerator(baseName) {
    this.baseName = "" + baseName;
    this.number = 0;
}

IdGenerator.prototype.next = function () {
    return "" + this.baseName + this.number++;
};

var gen = new IdGenerator("symbol_")
for (var i = 0; i < 100; i++) {
    console.log(gen.next());
}
ChaosPandion
  • 77,506
  • 18
  • 119
  • 157
0

If you only have 500 or so to choose from, you could just hash the contents of the symbol together with a JS MD5 implementation, or even just use a JS UUID generator like this one: http://ajaxian.com/archives/uuid-generator-in-javascript

If this data is persistent across sessions and stored serverside, you'd be better off doing this part on the server.

Winfield Trail
  • 5,535
  • 2
  • 27
  • 43