开发者

javascript randoms?

I have an object that looks something like

names = {
  m: [
       'adam',
       'luke',
       'mark',
       'john'
     ],
  f: [
       'lucy',
       'mary',
       'jill',
       'racheal'
     ],
 开发者_如何学编程 l: [
       'smith',
       'hancock',
       'williams',
       'browne'
     ]
};

What I want to do is.

I get a string that looks like

{m} {l} is a male name, so {f} {l} is a female name, {r} {l} must me a either/or(random) gender name

And I want it to randomly be populated from the correct keys.

so you might get

luke browne is a male name, so racheal smith is a female name, mary browne must be a either/or(random) gender name

How would I go about doing this?

the function skeleton would look something like

function names(mask, callback){}

and the last line of the code would be something like callback(replaced)


You can use Math.random() to get a random value between 0 and 1. From there you can use Math.ceil() or Math.floor() with multiplication to get the desired range of values.


There are two parts of JavaScript that you need to know for this question:

  1. Math.random(), which is the only way to generate random numbers within JavaScript. It generates a number between 0 and 1; you can get a random integer between 0 and n - 1 with Math.floor(Math.random() * n).
  2. Regular expressions, for getting the "template" strings out of the mask, and for performing the replacement. The expression mask.match(/{.}/)[0] will give you the first template string in the mask (e.g. '{m}' in the given case).

To replace the '{m}' in mask with 'foo', you'd write

mask = mask.replace(/{m}/, 'foo');

Put all the concepts above together in a while (mask.match(/{.}/) loop, and voila!


First, you have to match a character inside braces, you can use regular expression to do it:

/\{(\w)\}/g

Also note that your template has {r} tag, which is not present in the object. Let's populate it ourselves:

names.r = names.m.concat(names.f);

Here, elements in names.r are names from both names.m and names.f. Then you can use string.replace to replace them.

Instead of providing a substring that gets replaced, you can instead provide a function which computes the replacement string on the fly.

function replaceNames(mask, callback) {
    callback(mask.replace(/\{(\w)\}/g, function(all, category) {
        var arr = names[category];
        return arr[Math.floor(Math.random() * arr.length)];
    }));
}


You can do something like this:

function randomName(names){
    var _names = [];
    for(i in names) _names.push(i);
    var random = Math.floor(Math.random()*_names.length);
    if(random) random -= 1; // only m and f
    return names[_names[random]][Math.floor(Math.random()*names[_names[random]].length)];
    }


You should use two functions: the first to parse the mask, and then second to randomly choose names.

Parsing the mask is straightforward enough. A regular expression can be used to retrieve an array of all the keys. Then you can loop through these performing the replacements.

function names(mask, callback) {

    var replaced = mask;

    //get an array of all the keys (with braces)
    var keys = mask.match(/{[mflr]}/g);

    for (var i=0; i<keys.length; i++) {

        //extract the "f" from "{f}"
        var type = keys[i].charAt(1);

        //make the replacement
        replaced = replaced.replace(keys[i], getNameFromObject(type));
    }

    callback(replaced);
}

The role of the second function is to choose a name from the object of names, given a certain type. In the question, this object has the identifier "names". This is also the identifier of the function that parses the mask. I recommend renaming the object to something similar to "allNames" because it will avoid possible namespace conflicts and is more expressive of the nature of the object.

As suggested, Math.random() and Math.floor() are used to choose a random index of a name. You should not use Math.ceil(), as this might cause an off-by-one error, or require subtraction by one.

function getNameFromObject(type) {

    if (type == 'r')
        type = (Math.random() > 0.5)? 'm' : 'f';

    //assuming that the object has the type of name being requested
    //NOTE: "allNames" is used as the identifier of the data object
    var possibleNames = allNames[type];

    //assuming the arrays can't be empty
    var randomIndex = Math.floor(Math.random() * possibleNames.length);
    return possibleNames[randomIndex];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜