【问题标题】:Javascript - Randomly choosing items within an object, but not choosing excluded itemsJavascript - 随机选择对象中的项目,但不选择排除的项目
【发布时间】:2017-09-14 16:15:50
【问题描述】:

我正在从事一个项目,我需要在一个对象中包含许多函数,以便我可以使用以不同方式组合以访问不同函数的变量来访问它们。我还没有在我的主项目中写这个,只是将它作为一种方法进行了测试,我将把测试代码放在下面,希望能更好地解释我在说什么。这个对象中会有很多函数,目的是让其中一个在按下按钮时随机运行。

我想要做的一个关键部分是用户可以从随机选择中排除他们想要的任何功能,这就是给我带来一些问题的原因。我阅读了很多其他问题的解决方案,但它们都只是有点偏离(或者至少我还不知道如何将它们应用到这个问题上)。我尝试的第一件事是使用一个数组,根据用户勾选的选项,排除或添加项目,然后从中随机选择以获得随机数,但我担心大约 300 个项目的数组只会减慢速度或导致比真正有用的问题更多的问题,所以我放弃了这一点。我也查找了如何从随机生成中排除数字,但这倾向于使用 for 循环并且仅适用于被排除的少数数字 - 之后我想这也会导致问题。我也研究了从随机生成中排除数字范围,但不能保证用户排除的项目在对象中彼此相邻,因此会导致问题。

我的计划是在对象键的末尾添加一个数字;随机数生成器将从所有未排除的数字中进行选择(排除基于密钥的其他部分,例如排除下面测试中的所有“沙拉”选项),然后选择该数字以及两个或三个其他变量补关键把我们带到一个实际的东西上。因此,在下面的主题中,可能会根据用户选择的选项和随机数分别选择“培根”+“汉堡”+“生菜”+“17”,并可能导致第 17 个基于培根汉堡生菜的警报 - I我不是在做某种叫卖食物的应用程序,顺便说一下,这真的只是一个演示......

这...希望没有听起来那么复杂。我想我已经解释得很糟糕了,所以如果我能澄清一些事情,请告诉我。或者,如果为此目的在对象内嵌套函数是直接愚蠢的,告诉我!我想学习最好的做事方式,而不是摸索一些丑陋和不雅的东西!

var food;
var type;
var func = {
  cheeseburger: function() {alert("This is CHEESE BURGER");},
  baconburger: function() {alert("BACON BURGER reigns supreme!");},
  cheesesalad: function() {alert("CHEESE SALAD hahahaha");},
  baconsalad: function() {alert("BACON SALAD! That's right!");}
 };

$(".cheese").click(function() {
  food = "cheese";
  $(".test").html(food);
});

$(".bacon").click(function() {
  food = "bacon";
  $(".test").html(food);
});

$(".burger").click(function() {
  type = "burger";
  $(".test2").html(type);
});

$(".salad").click(function() {
  type = "salad";
  $(".test2").html(type);
});

$(".go").click(function() {
  func [food + type]();
});

【问题讨论】:

  • 我认为您对删除排除项目的数组的最初想法是最好的。不要担心优化,除非你发现它实际上太慢了。
  • 实现计划的代码在哪里?你有什么问题?

标签: javascript object random


【解决方案1】:
const funcs = [
   v => alert(v),
   v => console.log(v),
   v => alert( v + 1)
];

const excluded = new Set();

//to exclude a function
excluded.add(2);

function random(...args){
  do {
    var i = Math.floor( Math.random() * funcs.length );
  } while( excluded.has( i ) );
  funcs[i](...args);
}

 //test it
 random("test");

【讨论】:

  • 这很有趣,我想我遵循它 - 在上面的代码中,函数 'alert(v + 1)' 将被排除,对吗?你能向我解释一下函数 random(...args) 吗?以及如何从排除池中删除东西以再次将它们添加到 funcs 中?
  • @batbut 是的。这将所有参数作为参数(所以它将是 ["test"]),然后它使用该参数调用随机函数。要删除,只需执行 exclude.remove(2)
【解决方案2】:

首先,您需要一些属性来启用或禁用功能。

var func = {
    cheeseburger: {f: function() {...}, enabled: true},
    baconburger: {f: function() {...}, enabled: true},
    cheesesalad: {f: function() {...}, enabled: true},
    baconsalad: {f: function() {...}, enabled: true},
  ...
};

然后是一个随机选择一个忽略禁用的函数的函数。

这里出现第一个问题:如果你只是随机选择一个直到找到一个 这不是禁用的,随着禁用的数量的增长,它将需要 更长的时间才能找到启用的。

更简单的解决方案是使用如下缓存:

var cache;
function updateCache(){ // Using function we can update it when needed.
    cache = Object.keys(func).filter(k=>func[k].enabled);
};
updateCache();

那么你也需要启用/禁用方法:

function enable(fn) {
    func[fn].enabled = true;
    updateCache();
};
function disable(fn) {
    func[fn].enabled = false;
    updateCache();
};

最后,您只需要从缓存中选择功能键:

function callRandomFn(){
    var k = Math.floor(Math.random() * cache.length);
    return fn[cache[k]]();
};

【讨论】:

  • 这...看起来非常简洁!启用和禁用功能是否会同时启用或禁用多个功能? k 在您的 updateCache() 函数中代表什么?迭代器?
  • “一次”是什么意思? Javascript 是异步的,但不是并发的。 k 在您所说的上下文中是 *arrow 函数的参数”传递给 [array].filter() 方法,以告知必须在结果数组中删除(过滤)哪些元素。
  • 我想我明白了,但我在测试中实际实现这一点时遇到了麻烦。我现在实际上无法获得耗尽对象的功能,这是主要障碍。使用之前的方法 (func[cheesesalad]()) 不起作用,func[cheesesalad[]} 或 func[cheesesalad[f],甚至 func.cheesesalad 也不起作用。我知道我显然遗漏了一些明显的东西,但是您能就这里的语法提出建议吗?
  • @batbut func["cheesesalad"].f(...)
猜你喜欢
  • 2021-05-04
  • 2015-04-07
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 2020-07-01
相关资源
最近更新 更多