[英]How to get 10 non-repeating random objects from nested array in Javascript?
I have an object like this: 我有一个这样的对象:
var database = [
{
category: 'CPUs',
id: 1,
products: [Product, Product, Product] //Product is an object
},
{
category: 'GPUs',
id: 2,
products: [Product, Product]
}
];
and so on.. 等等..
I'd like to get 10 random products in total, non-repeating. 我想总共获得10个随机产品,且不重复。 There can be more than one from the same category, as long as they are different products. 只要是不同的产品,同一类别中可以有多个。 How can I do this? 我怎样才能做到这一点? I tried this: 我尝试了这个:
function getRandomFromObject(){
var productsCollected = [];
while(productsCollected.length < 10){
var randomCategory = database[Math.floor(Math.random()*database.length)];
var randomProduct = randomCategory.products[Math.floor(Math.random()*randomCategory.products.length)];
productsCollected.push(randomProduct);
}
return productsCollected;
}
Things become easier if you first concatenate all the products into one array, then shuffle that array and finally take the first 10 from that: 如果首先将所有产品连接到一个阵列中,然后将其随机组合,最后从中取出前10个,则事情会变得更容易:
function shuffle(a) { for (let i = a.length; i; i--) { let j = Math.floor(Math.random() * i); [a[i - 1], a[j]] = [a[j], a[i - 1]]; } return a; } function getRandomFromObject(count){ return shuffle([].concat(...database.map(o => o.products))).slice(0, count); } var database = [ { category: 'CPUs', id: 1, products: ['a', 'b', 'c'] //Product is an object }, { category: 'GPUs', id: 2, products: ['d', 'e'] }, { category: 'GPUs', id: 3, products: ['f', 'g', 'h', 'i', 'j'] } ]; console.log(getRandomFromObject(10).join(','));
Addendum: If you can have the same Product object occurring in different categories, then apply a Set
to the concatenated array, so to eliminate these duplicates: 附录:如果可以使同一Product对象出现在不同的类别中,则将Set
应用于连接的数组,以便消除这些重复项:
return shuffle([...new Set([].concat(...database.map(o => o.products)))]).slice(0, count);
As you asked in comments for ES5, and the need to consider products with the same ISBN property as the same products, here is the code for that: 正如您在对ES5的评论中所问的那样,以及需要考虑具有与相同产品相同的ISBN属性的产品,以下是该代码:
function shuffle(a) { for (var i = a.length; i; i--) { var j = Math.floor(Math.random() * i); var temp = a[i - 1]; a[i - 1] = a[j]; a[j] = temp; } return a; } function getRandomFromObject(count){ var uniq = {}; // Unique list of products, keyed by ISBN database.forEach(function (o) { o.products.forEach(function (product) { uniq[product.isbn] = product; }); }); var products = []; for (product in uniq) { products.push(uniq[product]); } return shuffle(products).slice(0, count); } var database = [ { category: 'CPUs', id: 1, products: [{ isbn: 'a' }, { isbn: 'b' }, { isbn: 'c' }] //Product is an object }, { category: 'GPUs', id: 2, products: [{ isbn: 'd' }, { isbn: 'a' }, { isbn: 'j' }] // has same isbn as in CPUs }, { category: 'Others', id: 3, products: [{ isbn: 'e' }, { isbn: 'f' }, { isbn: 'g' }, { isbn: 'h' }, { isbn: 'i' }] } ]; console.log(getRandomFromObject(10));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.