【问题标题】:Create a new array from a random() generator?从 random() 生成器创建一个新数组?
【发布时间】:2021-10-20 16:21:15
【问题描述】:

我正在尝试创建一个新数组,其中包含 5 个随机名称,这些名称取自具有 897 个名称的数组。这是我试图做的,但我不确定如何指定我只想要 5 个名字:

for(let i = 0; i < pokemon.all().length; i++){
    pokedex = [i];
};
app.get('/dex', (req, res) => {
    res.send(pokedex)
});

【问题讨论】:

  • pokemon.all().length 是您指定的位置,i
  • 但是你的代码看起来有点乱,你会运行 for 循环 5 次(那里不需要口袋妖怪),你会有 pokedex.push() 口袋妖怪的值,但你想要它是随机的,所以每个循环你都会抛出一个 0-897 之间的随机数来添加到 pokedex 数组中。完成后,您可以前往 /dex 查看结果。
  • shuffle it 然后slice it 获得前5个,还要注意在路由器中间件之外执行代码,只会在服务器启动时运行一次
  • @blanknamefornow 我明白了,这是有道理的。我运行 for 循环 5 次,然后我会有 pokedex = 新数组?然后使用 pokedex.push() 将 5 个随机名称推送到新的 pokedex 数组中?
  • @LawrenceCherone ...从近 900 个姓名的数组中随机挑选 5 个项目不是比随机排列更容易甚至更有效吗?

标签: javascript arrays random


【解决方案1】:

function pickNOf(list, n) {
  // - create a new shallow array copy.
  // - does decouple the original reference, thus it
  //   prevents its further mutation by e.g. `splice`.
  list = Array.from(list);

  // - creates and returns an array of the desired length.
  return Array.from({ length: n }, () => list.splice(
    // - `splice` does mutate the list by removing a
    //   single item from its randomly chosen index.
    Math.floor(Math.random() * list.length), 1
  )[0]);
}
const listOfAllPokemonNames = [
  "Bulbasaur", "Ivysaur", "Venusaur", "Charmander", "Charmeleon",
  "Charizard", "Squirtle", "Wartortle", "Blastoise", "Caterpie",
  "Metapod", "Butterfree", "Weedle", "Kakuna", "Beedrill", "Pidgey"
];

console.log(
  "pickNOf(listOfAllPokemonNames, 5) ...",
  pickNOf(listOfAllPokemonNames, 5)
);
console.log(
  "pickNOf(listOfAllPokemonNames, 9) ...",
  pickNOf(listOfAllPokemonNames, 9)
);
console.log(
  "pickNOf(listOfAllPokemonNames, 3) ...",
  pickNOf(listOfAllPokemonNames, 3)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

在 OP 代码中的使用看起来像这样......

function pickNOf(list, n) {
  list = Array.from(list);

  return Array.from({ length: n }, () => list.splice(
    Math.floor(Math.random() * list.length), 1
  )[0]);
}

app.get('/dex', (req, res) => {
  res.send(pickNOf(pokemon.all(), 5))
});

【讨论】:

  • 收到了反对票,我真的很好奇上述方法是如何应得的。据我所知,该方法的策略简单、干净/精益,并且非常有效地解决了从任何给定数组中选择N 随机但唯一值的任务。不需要改组,因为该方法通过切片每轮随机items的数量来消耗/减少它正在操作的数组
【解决方案2】:

看看这个,使用 Math.random() 生成随机索引并从 pokemons 数组中获取它,然后将 pokemons 中的值取消设置为 pokedex 中没有 doublon。

let pokemons = ['pika1','pika2','pika3','pika4','pika5','pika6','pika7']
let pokedex = [];
for (i = 0; i < 5; i++) {
  id = Math.floor(Math.random() * pokemons.length);
  pokedex.push(pokemons[id]);
  pokemons.slice(i,1)
}
//app.send() here...
console.log(pokedex)

编辑:考虑到你在这个 npm 包中有一个 pokemon.random() generator(?)。只需使用:

let pokedex = [];
for(let i = 0; i < 5; i++)    
    pokedex.push(pokemon.random());
app.get('/dex', (req, res) => {     
        res.send(pokedex) 
});

编辑 N°2:使用对象

let pokedex = [];
for (i = 0; i < 5; i++) {
  let pokemon = {
  name:pokemon.random(),
  attack:Math.floor(Math.random() * (100 - 50 + 1) +50),
  defense:Math.floor(Math.random() * (100 - 50 + 1) +50)
  };
  pokedex.push(pokemon);
}

function attack(attacker,defenser)
{
  defenser.defense -= attacker.attack
  return attacker && defenser;
}

function fakeMatch(attacker,defenser)
{
  attack(attacker,defenser)
}
console.log(pokedex)
fakeMatch(pokedex[0],pokedex[3])
console.log('RESULT Pokedex 0 attacked Pokedex 3')
console.log(pokedex)

编辑 N°3:具有功能的对象(正确方式)

let pokemons = ['pika1', 'pika2', 'pika3', 'pika4', 'pika5', 'pika6', 'pika7']
let pokedex = [];
for (i = 0; i < 5; i++) {
  let id = Math.floor(Math.random() * pokemons.length);
  let pkm = {
    name: pokemons[id],
    life: 100,
    strenght: Math.floor(Math.random() * (100 - 50 + 1) + 50),
    defense: Math.floor(Math.random() * (100 - 50 + 1) + 50),
    attack: function(target) {
      target.life -= this.strenght;
      console.log(this.name + ' attack ' + target.name)
      console.log(target.name + ' loose ' + this.strenght + ' of life')
      //Test if life > 0 or anything else with % defense etc...
      if (target.life <= 0) {
        console.log(target.name + ' is dead')
      }
    }
  };
  pokedex.push(pkm);
  pokemons.slice(id, 1)
}
pokedex[0].attack(pokedex[1]);

【讨论】:

  • 感谢这个例子!!我使用了这个例子,但做了一些修改。我应该提到这个 npm 包中有一个 pokemon.random() 生成器(?)。所以我使用了这个let pokedex = [] for(let i = 0; i &lt; 5; i++){ pokedex.push(pokemon.random()) }; app.get('/dex', (req, res) =&gt; { res.send(pokedex) }); 我需要记住 Global 的规则,因为那让我很受挫!
  • 不客气。希望一切正常。不要犹豫,问。
  • 谢谢!它正在工作,我感谢您的帮助。我想知道您是否可以偶然帮助我将这 5 个随机名称转换为包括随机攻击 #(50-100) 和随机防御 #(0-100) 的对象。我想创建这样的东西:let newDex = { 'pokemon': pokedex[0], 'attack': Math.floor(Math.random()* 100) + 50, 'defense': Math.floor(Math.random()* 100) } 我可以为 1 个 pokemon 完成它,但我需要像这样再添加 4 个吗?或者有没有我可以使用的函数或 for 循环来做到这一点?
  • 为您编辑 :)
  • 哇,非常感谢!我使用了你的大部分代码,并确保在使用之前我理解了它。做了一些修改,但你的代码帮了大忙。我肯定会研究我没有用来检查的东西。再次,非常感谢!
猜你喜欢
  • 2017-10-11
  • 2016-07-09
  • 2018-11-24
  • 1970-01-01
  • 2013-09-25
  • 2016-12-18
  • 1970-01-01
  • 2013-01-03
  • 2012-12-16
相关资源
最近更新 更多