【问题标题】:Random combinations from different arrays with not repetition来自不同数组的随机组合,不重复
【发布时间】:2021-10-19 04:23:19
【问题描述】:

对网站和 javascript 非常陌生。 在论坛上找了一段时间,但找不到我要找的答案,或者至少无法理解我阅读的主题。

我正在尝试制作一个生成器来根据需要创建上述数组的任意组合,而无需重复组合并且每次迭代仅使用每个数组的一项。我还需要添加一些额外的需求,例如迭代的唯一 id 和用于标记所有属性具有相同值的迭代的额外属性。

这是代码

var accesories = ["pijama" , "urban" , "joker" , "joyboy" , "crypto"];
var hats = accesories;
var tshirts = accesories;
var boots = accesories;


var cards = [];

function randomizeParts() {
model.accesories = accesories[Math.floor(Math.random() * 5)];
model.hats = hats[Math.floor(Math.random() * 5)];
model.tshirts = tshirts[Math.floor(Math.random() * 5)];
model.boots = boots[Math.floor(Math.random() * 5)];
};


function addInsomnio (quantity) {

for (let i = 1 ; i <= quantity ; i++){
    model = {
        id : 0,
        accesories: 0,
        hats: 0,
        tshirts: 0,
        boots: 0}

    //adding four digits id

    i < 10 ? model.id = '000' + i : i < 100 ? model.id = '00' + i : i < 1000 ? model.id = '0' + i : i <= 10000 ? model.id = i :false;

    //randomizing parts

    randomizeParts() 

    //checking if rarity was generated

   model.accesories === model.hats && model.accesories === model.tshirts && model.accesories === model.boots ? model.rarity = "original" : false;
    
    //checking its unique
    
   // ????

    //Pushing a beautifull brand new and unique card

    cards.push(model);
 }

};

有没有办法在推送之前将随机 模型cards 中的现有对象进行比较,如果该组合已经存在,则可以根据需要将其随机化多次?

注意:计划使用一次,仅生成一个 10,000 个项目的 json 作为对 photoshop 脚本的支持。

【问题讨论】:

  • 这是典型的数组大小 (5) 和数量 (4) 吗?还是真实案例的规模或数量要大得多?
  • 这只是一个简化的版本来尝试脚本。我认为大小将接近 30,但数组的数量将始终为 4。
  • 您是否只是想以随机顺序获得 5x5x5x5 的排列? (即 5 个数组的 625 个总结果)
  • 这可能会派上用场:phrogz.net/lazy-cartesian-product
  • @Jamiec 是的,但不需要所有排列。

标签: javascript arrays sorting random generator


【解决方案1】:

您可以用一个唯一的数字来识别每个组合,并维护一组使用过的数字:

function choices(count, ...arrays) {
    let used = new Set;
    let size = arrays.reduce((size, arr) => size * arr.length, 1);
    if (count > size) count = size;
    let result = [];
    for (let i = 0; i < count; i++) {
        let k;
        do {
            k = Math.floor(Math.random() * size);
        } while (used.has(k));
        used.add(k);
        result.push(arrays.reduce((acc, arr) => {
            acc.push(arr[k % arr.length]);
            k = Math.floor(k / arr.length);
            return acc;
        }, []));
    }
    return result;
}

let accesories = ["a", "b", "c", "d", "e"];
let hats = ["A", "B", "C", "D", "E"];
let tshirts = ["1", "2", "3", "4", "5"];
let boots = [".", ";", "?", "!"];

// Get 10 choices:
let result = choices(10, accesories, hats, tshirts, boots);
console.log(result);

【讨论】:

  • 很抱歉,如果有很多问题要问,但我不理解解决方案的某些部分,而且我不想在不理解的情况下复制和粘贴它。你能解释一下 /let used = new Set;/ 和 /used.add(k)/ 是什么吗?
  • A Set 是一种存储唯一元素的数据结构,并允许快速检查它是否已经包含给定值。使用add 将值添加到其中。见documentation of Set。或者,您可以使用普通对象而不是Set,并使用used = {}used[k] = 1while (used[k])
  • 非常感谢!将研究文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
相关资源
最近更新 更多