压缩 JavaScript 随机句子生成器代码

3

我正在尝试创建一个生成器,它可以根据从不同单词数组中以随机确定的索引提取变量来创建半随机句子,并从数组中删除该单词以确保没有重复。

它可以工作,但不易于扩展。每当我想要从已在同一行中提取的数组中再次提取时,脚本就停止了。

document.getElementById("button").onclick = function() {
  genContent();
};

function genContent() {
 var content = "";
 lists();
// --- what works ---
  content += r(person).concat(" ", r(verb), "ed ");
  content += r(person).concat(", so ");
  content += r(person).concat(" is ", r(verb), "ing ");
  content += r(person);
  
// --- what I want to condense it down to ---
//  content += r(person).concat(" ", r(verb), "ed ", r(person), ", so ", r(person), " is ", r(verb), "ing ", r(person));


  document.getElementById("output").innerHTML = content.charAt(0).toUpperCase() + content.slice(1);
};

function r(array) {
  random = Math.floor(Math.random() * array.length);
  value = array[random];
  array.splice(random, 1);
  return value;
};

function lists() {

 person = ["Grace", "Jared", "Suzy", "Tommy"];
  verb = [
   "answer", "ask", "block", "call", 
    "delay", "expect", "follow", "greet", 
    "help", "inform", "join", "kick", 
    "label", "mark", "need", "order", 
    "pick", "question", "request", "signal",
    "trick", "visit", "warn"];
};
<div>
  <textarea id="output" output="" rows="8" style="width:50%; min-width:285px;" readonly="readonly">
    Click the button to generate a sentence.
  </textarea>
  <br>
  <input type="button" value="Make content" id="button">
</div>

(jsfiddle链接因为更容易编辑)

有任何想法可以实现类似于注释掉的代码(第15行)的效果吗?

4个回答

1

只是concat使得这个过程变得非常混乱吗?你可以这样做:

content = r(person) + " " + r(verb) + "ed " + r(person) + ", so "
    + r(person) + " is " + r(verb) + "ing " + r(person);

你也可以使用数组连接,这很方便,因为你可以在元素之间插入任何字符,并且你可以使用push()构建数组。
content = [r(person), " ", r(verb), "ed ", r(person), "
    , so ", r(person), " is ", r(verb), "ing ", r(person)];

content = content.join("");

1
你其实可以使用空格字符进行连接,这有助于清理并且不需要一些只是空白空间的数组条目! - spozun

0

document.querySelector("button").addEventListener('click', function() {
    var person = ["Grace", "Jared", "Suzy", "Tommy"];
    var verb = ["answer", "ask", "block", "call", "delay", "expect", "follow", "greet", "help", "inform", "join", "kick", "label", "mark", "need", "order", "pick", "question", "request", "signal", "trick", "visit", "warn"];
    document.getElementById("output").innerHTML = [r(person), r(verb) + "ed", r(person) + ", so", r(person), "is", r(verb) + "ing", r(person) + "."].join(" ");
});

function r(list) {
    return list.splice(Math.floor(Math.random() * list.length), 1)[0];
};
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet"/>
<div class="container">
  <button>Go</button>
  <div id="output"></div>
</div>


0

另一种方法是使用模板,例如:

"[P] [V]ed [P], so [P] is [V]ing [P]"

并使用.replace()方法与自定义回调函数:

var person = [
      "Grace", "Jared", "Suzy", "Tommy"
    ],
    verb = [
      "answer", "ask", "block", "call", 
      "delay", "expect", "follow", "greet", 
      "help", "inform", "join", "kick", 
      "label", "mark", "need", "order", 
      "pick", "question", "request", "signal",
      "trick", "visit", "warn"
    ];

var template = "[P] [V]ed [P], so [P] is [V]ing [P]";

var str = template.replace(/\[([PV])\]/g, function(m, p0) {
  var list = {'P': person, 'V': verb}[p0];
  return list.splice((Math.random() * list.length) | 0, 1);
});

console.log(str);


0

另一种方法/实现你的代码,只作为灵感。

//takes an Array, shuffles it in place (no copy), and returns the shuffled Array
function shuffle(arr){
    for(var len = arr.length, i=len, j, tmp; i--; ){
        j = Math.floor(Math.random() * (len-1));
        if(j>=i) ++j;
        tmp = arr[j];
        arr[j] = arr[i];
        arr[i] = tmp;
    }
    return arr;
}

//a utility to uppercase only the first-char of a string
function uppercaseFirstChar(str){
    return str.charAt(0).toUpperCase() + str.slice(1);
}

//stringpool, 
//the code never mutates this, so there's no need to ever reset it.
var strings = {//TODO: find a better name(space) than `strings`
    persons: [
        "Grace", "Jared", "Suzy", "Tommy"
    ],

    verbs: [
        "answer", "ask", "block", "call", 
        "delay", "expect", "follow", "greet", 
        "help", "inform", "join", "kick", 
        "label", "mark", "need", "order", 
        "pick", "question", "request", "signal",
        "trick", "visit", "warn"
    ]
}

//keep the tasks simple and clear. 
//this function builds and returns a random sentence. 
//no more, no less.
//it doesn't need to know what the result is used for
function randomSentence(){
    //don't mutate the string-pool, create a copy of the Arrays, and shuffle that
    var person = shuffle( strings.persons.slice() );
    var verb = shuffle( strings.verbs.slice() );

    //build the sentence, uppercase the first char, and return the result
    return uppercaseFirstChar(
        `${person[0]} ${verb[0]}ed ${person[1]}, so ${person[2]} is ${verb[1]}ing ${person[3]}`
    };


    //an example how you can reference the same person/verb multiple times in the same result
    //your r(array)-approach is not able to that; it's kind of destructive.
    //return `${person[0]} ${verb[0]}ed ${person[1]}; ${person[1]} has been ${verb[0]}ed by ${person[0]}`
};


document.getElementById("button").onclick = function() {
    document.getElementById("output").innerHTML = randomSentence();
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接