如何从集合中随机选择项目

How to select random items from a set

本文关键字:随机 选择 项目 集合      更新时间:2023-09-26

我正在尝试创建一个网站,该网站将调用我的json文件,并使用这些信息随机化结果。例如,在我的json文件中有100个项目。所以我试图弄清楚如何从所有这些信息中,每次加载页面时,我只能随机选择5或6个。

这是我当前的脚本

function ajax_get_json(){
var hr = new XMLHttpRequest();     
hr.open("GET", "lyrics.json", true);
hr.setRequestHeader("Content-type", "application/json", true);
   hr.onreadystatechange = function() {
    if(hr.readyState == 4 && hr.status == 200) {
       var data = JSON.parse (hr.responseText);
       var results = document.getElementById("results");
       results.innerHTML = "";
       for (var obj in data){ 
            results.innerHTML += data[obj].user;
        }
}
   }
hr.send(null); 
results.innerHTML = "requesting...";

}

我希望有人能帮忙,我对此了解不多,正在努力为我正在创作的这件艺术品学习。

以下是json文件的外观示例这是一首德拉克歌曲的样本,其想法是最终从一堆不同的歌词中随机创作诗歌。我很抱歉,它说用户,所有这一切可能看起来很混乱,但我只是修复了一些东西,使其按照我需要的方式工作,这就是为什么它仍然说用户。

{
"u1":{ "user":"I might be too strong out on compliments"},
"u2":{ "user":"Overdose on confidence"},
"u3":{ "user":"Started not to give a fuck and stopped fearing the consequence"},
"u4":{ "user":"Drinking every night because we drink to my accomplishments"},
"u5":{ "user":"Faded way too long I'm floating in and out of consciousness"},
"u6":{ "user":"And they sayin' I'm back, I'd agree with that"},
"u7":{ "user":"I just take my time with all this shit, I still believe in that"},
"u8":{ "user":"I had someone tell me I fell off, ooh I needed that"},
"u9":{ "user":"And they wanna see me pick back up, well where'd I leave it at"},
"u10":{ "user":"I know I exaggerated things, now I got it like that"}
}

文件的名称lyrics.json

这是我当前的脚本更新了你告诉我的关于的更改

function getRandomItemsFrom(){
var hr = new XMLHttpRequest();
hr.open("GET", "lyrics.json", true);
hr.setRequestHeader("Content-type", "application/json", true);
   hr.onreadystatechange = function() {
    if(hr.readyState == 4 && hr.status == 200) {
       var data = JSON.parse (hr.responseText);
       var results = document.getElementById("results");
       var lyricsArray = [];
       for ( prop in data ) {
           lyricsArray.push(data[prop].user);
        }
        var randomLyrics = getRandomItemsFrom(data.lyrics, 5);
        Results.innerHTML = "<div>" + data.lyrics.join("</div><div>") + "</div>";
}
   }
hr.send(null); 
results.innerHTML = "requesting...";

}

我想我还有几个问题,当你说我需要把歌词放入数组时,你的意思是它们本质上应该是这种格式的吗

{
 "items" : [
  {
   "lyrics" : "content1"
  },
  {
  "lyrics" : "content2"
  },
  {
  "lyrics" : "content3"
  }
 ]
}

所以,如果我的.json文件被更改为脚本中的样子,我会更改的位置吗

lyricsArray.push(data[prop].user

lyricsArray.push(data[item].user

使用随机数生成器生成一个介于0和n-1之间的随机数,其中n=JSON数组的长度:

Math.floor(Math.random() * (n - 1)) + 1

这样做5或6次,然后使用您获得的值按索引访问数组中的项目以显示给用户。

正如@CoryDanielson所指出的,你还应该检查一下,确保你不会得到两次相同的数字,这很可能是数组越小。

顺便说一句,您应该使用JQuery中的$.get$('#results').html来避免XHR和DOM的低级细节。

另一种方法:

首先将JSON文件中的所有100个项目按顺序加载到数组中。然后使用Fisher Yates洗牌来洗牌你的阵列中的前五到六个项目(你不需要洗牌,因为你不使用它们。)最后,使用部分洗牌阵列中的第一个项目。

这将从数组中返回一组唯一项。结果集的长度取决于传入的第二个参数

它的工作原理是生成0和数组长度减1之间的随机数。如果随机数尚未使用,它将在数组中随机数的位置获取项目,并将其存储到结果数组中。它会执行此操作,直到将numberOfItems参数指定的项目添加到结果数组中,然后返回结果数组。

随着arr和numberOfItems越来越接近,它变得越来越低效,尤其是在这些数字很大的情况下。从5个长度的数组中获得5个随机项目不是很有效,但不应该花费太长时间,但从1000个数组中获得1000个随机项目将是非常低效的。对于您的用例(从一个长度为100的数组中随机抽取5个项目),此代码的低效率可以忽略不计。

http://jsfiddle.net/CoryDanielson/S64Hy/

function getRandomItemsFrom(arr, numberOfItems) {
    if ( arr instanceof Array === false || arr.length === 0 ) return false;
    if ( numberOfItems === undefined || numberOfItems <= 0 ) return false;
    var results     = [],
        usedIndexes = {},
        randomIndex;
    while ( results.length !== numberOfItems ) {
        randomIndex = Math.floor(Math.random() * arr.length);
        if ( usedIndexes.hasOwnProperty(randomIndex) === false ) {
            usedIndexes[randomIndex] = true;
            results.push(arr[randomIndex]);
        }
    }
    return results;
}

用法:

var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
getRandomItemsFrom(alphabet, 10);
result => ["v", "m", "e", "x", "l", "s", "b", "d", "w", "p"]

代码用法:

首先,将getRandomItemsFrom函数添加到具有上述ajax_get_json函数的同一文件中。然后将处理检索lyrics.json的代码更改为这样的代码。

hr.onreadystatechange = function() {
    if(hr.readyState == 4 && hr.status == 200) {
       var data = JSON.parse (hr.responseText);
       var results = document.getElementById("results");
       // get the lyrics in an array
       var lyricsArray = [];
       for ( prop in data ) {
           lyricsArray.push(data[prop].user);
       }
       // Get random lyrics           
       var randomLyrics = getRandomItemsFrom(data.lyrics, 5);
       results.innerHTML = "<div>" + data.lyrics.join("</div><div>") + "</div>";
}