避免Math.random()函数

时间:2017-05-15 10:06:32

标签: javascript jquery arrays sorting

我必须列出单词:

<div class="first-word-list">
  <span>apple</span>
  <span>sea</span>
  <span>ship</span>
</div>

<div class="second-word-list">
  <span>duck</span>
  <span>tale</span>
  <span>jewelry</span>
</div>

客户端可以在这些列表中添加任何单词,因此不仅仅是这6个单词。 我正在使用一个函数,当它在click事件时,它会改变这个结构在这两个列表之间创建组合的单词:

<div class="first-word"></div><div class="second-word"></div>

$('.first-word').click(function(){
  $('.first-word').text($(".first-word-list span").eq(Math.floor(Math.random()*firstWordLength)).text());
});

$('.second-word').click(function(){
  $('.second-word').text($(".second-word-list span").eq(Math.floor(Math.random()*firstWordLength)).text());
});

因此,如果用户点击.first-word并点击.second-word,则会显示以下内容:

<div class="first-word">sea</div><div class="second-word">tale</div>

但是我想阻止/避免显示shipjewelry的组合。由于我使用的是随机函数,就像我之前写的那样,单词列表会增长,我需要一种方法来控制哪些单词组合不会显示。知道怎么做吗?

更新 客户端将在两个新的自定义字段上编写禁止的组合,这些字段将在新列表中输出,如下所示:

<div class="banned-combinations">
   <div><span>ship</span><span>jewelry</span></div>
   <div><span>apple</span><span>duck</span></div>
</div>

2 个答案:

答案 0 :(得分:1)

这是一个代码段,允许您动态地将单词添加到任一列表,并从这些列表中选择单词以将其标记为禁止的组合。一旦你想要输入所有内容,你可以点击两个随机单词,将它们替换为一个新的随机单词(可能再次只是同一个单词),同时考虑到禁止组合:

// Allow adding words to either word list:
$(".add-word").on("change keydown", function (e) {
    if (e.which && e.which != 13) return;
    $(this).before($("<span>").text($(this).val()));
    $(this).val('');
});

// Allow selecting words by clicking them
$(".word-list").on("click", "span", function () {
    $(".selected", $(this).parent()).removeClass("selected");
    $(this).addClass("selected");
    showButton();
});

// Allow forbidding pairs of selected words:
$("#forbid").click(function () {
    $(".forbidden").append(
        $("<div>").append(
            $(".selected").removeClass("selected").clone(),
            $("<button>").addClass("del").text("Del")
        )
    );
    showButton();
});

// Remove forbidden pair:
$(document).on("click", ".del", function () {
    $(this).parent().remove();
});

// Hide/show button depending on whether we have enough selected words:
function showButton() {
    $("#forbid").toggle($(".selected").length == 2);
}

// Main algorithm:
$(".random-word").click(function () {
    var index = $(this).index(".random-word");
    // Get word that is not clicked:
    var otherword = $(".random-word").eq(1-index).text();
    // Get all words from corresponding list
    var words = $("span", $(".word-list").eq(index)).map(function () {
        return $(this).text();
    }).get();
    // Get list of forbidden words that are linked with the other (non-clicked) word
    var forbidden = $('.forbidden div').filter(function () {
        return $('span', this).eq(1-index).text() == otherword;
    }).map(function () {
        return $('span', this).eq(index).text();
    }).get();
    // Derive the list of allowed words, taking all words, filtering out what is forbidden
    var allowed = words.filter(function (txt) {
        return forbidden.indexOf(txt) == -1;
    });
    // Pick a random from these allowed words:
    $(this).text(allowed.length 
        ? allowed[Math.floor(Math.random() * allowed.length)]
        : "(none)"
    );
});

showButton();

// *** Upon special request following was added ***
// Algorithm for choosing random pair in one go:
$("#choose").click(function () {
    // Get all words from both lists
    var words = $(".word-list").get().map(function (list) {
        return $("span", list).get().map(function (span) {
            return $(span).text();
        });
    });
    // Get list of forbidden words pairs
    var forbidden = $('.forbidden div').get().map(function (div) {
        return $('span', div).get().map(function (span) {
            return $(span).text();
        });
    });
    // Derive the list of allowed pairs, taking all pairs, filtering out what is forbidden
    var allowed = words[0].reduce(function (pairs, word) {
        // Get list of forbidden second words, given the first word
        var exclude = forbidden.filter(function(pair) {
            return pair[0] == word;
        }).map(function (pair) {
            return pair[1]; // extract second word of the pair
        });
        // Filter all second words, excluding those that are forbidden pairs with first word.
        return pairs.concat(words[1].filter(function (word2) {
            return exclude.indexOf(word2) == -1;
        }).map(function (word2) {
            return [word, word2];
        }));
    }, []);
    // Pick a random pair from these allowed pairs:
    var randomPair = allowed.length 
        ? allowed[Math.floor(Math.random() * allowed.length)]
        : ["(none)", "(none)"];
    // Display the pair
    $(".random-word").each(function (i) {
        $(this).text(randomPair[i]);
    });
});
span {margin-left: 2px; margin-right: 2px}
span.selected {background-color: yellow}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<b>First word list:</b>
<div class="word-list">
  <span>apple</span>
  <span>sea</span>
  <span>ship</span>
  <input class="add-word" size=10>
</div>
<b>Second word list:</b>
<div class="word-list">
  <span>duck</span>
  <span>tale</span>
  <span>jewelry</span>
  <input class="add-word" size=10>
</div>
<button id="forbid">Add combination as forbidden</button><br>
<b>Forbidden combinations:</b>
<div class="forbidden">
</div>
<b>Random Pair (click a word to reselect a random, allowed word):</b>
<div class="random-word">sea</div><div class="random-word">tale</div>
<button id="choose">Random Pick Both</button>

答案 1 :(得分:0)

我不确定你要如何处理添加禁用的选项,但如果一切都需要动态,那么你总是可以使用字典(对象)。

var bannedOptions = { 
    'ship': { 
        'jewelry': true 
    }
};

当您去检查某个选项是否有效时,您可以执行以下操作:

// Here I'm using truthy checks,you can always add a != null 
// if you want false or something to be a valid value
if(bannedOptions[word1] && bannedOptions[word1][word2]) {
    // It's invalid
} else {
    // Valid
}

如果您想添加新的无效选项,可以

if(!bannedOptions[newWord]) bannedOptions[newWord] = {};
bannedOptions[newWord][invalidWord] = true;

如果您想删除无效选项,可以执行以下操作:

bannedOptions[word1][word2] = false;

delete bannedOptions[word1][word2];

使用字典可以在想要查看组合是否无效时进行超快速检查。

它超级动态,所以你不必担心索引或任何东西,因为单词本身就是键......只要单词作为字符串被访问,你就可以拥有像{这样的符号在单词中{1}},-'等。