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

Javascript 如何从集合中选择随机项,javascript,json,random,Javascript,Json,Random,我正在尝试创建一个网站,该网站将调用我的json文件,并使用这些信息将结果随机化。例如,我的json文件中有100个条目。因此,我试图找出如何从所有这些信息中,我只能选择,比如说每次加载页面时随机选择5或6个 这是我目前的剧本 function ajax_get_json(){ var hr = new XMLHttpRequest(); hr.open("GET", "lyrics.json", true); hr.setRequestHeader("Content-type", "

我正在尝试创建一个网站,该网站将调用我的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"}
}
文件lyris.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...";
因此,如果我的.json文件被更改为脚本中的那样,我会更改它的位置吗

lyricsArray.push(data[prop].user


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

Math.floor(Math.random() * (n - 1)) + 1
这样做5或6次,并使用您通过索引访问数组中的项所获得的值显示给用户

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

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

另一种方法:


首先,按顺序将JSON文件中的100个项目全部加载到数组中。然后使用来洗牌数组中的前五个或六个项目,因为您不使用它们,所以不需要洗牌其余的项目。最后,使用部分无序数组中的第一个项目。

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

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

随着arr和numberOfItems的距离越来越近,效率越来越低,特别是如果这些数字很大的话。从5个长度的数组中获取5个随机项不是很有效,但不会花费太长时间,但是从1000个长度的数组中获取1000个随机项将是非常低效的。对于从100个长度的数组中获取5个随机项的用例,此代码的低效性可以忽略不计

代码的用法: 首先,将getRandomItemsFrom函数添加到具有上述ajax\u get\u json函数的同一文件中。然后将处理检索lyris.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>";
}

嗯…你有一个项目数组,想生成一个随机数来选择一个项目吗?这不是“随机JSON”。为什么不使用jQuery呢?使用parseIntMath.random*n;相反如果Math.random生成.999999,则您的Math.floor。。。结果是98而不是99。你也会有一个很好的上限。忘记了+1。对随机数和正式事件都做不好。进行了编辑。我假设一个足够大的播放列表并不现实,但你指出这一点是对的。谢谢你的帮助,我打算尝试一下,所以我仍然有一些问题,很可能是因为我从来没有真正做过很多,但是,我想我不太确定我应该把它插到哪里,或者它是否只适用于jQuery脚本,或者它是否可以插到我正在使用的脚本上。我的json文件的名称是Lyps.json,我想在您发送给我的脚本的某个地方插入帽子。谢谢你的帮助!将它与ajax\u get\u json函数放在同一个文件中。在onreadystatechange函数中,您可以调用getRandomItemsFromdata,5来检索5个歌词的数组。然后,您可以在歌词上循环,添加一些HTML,并将它们放入results.innerHTML。不过,我必须看一个lyris.json的示例才能给你一个更精确的答案。嘿,更新了我的json文件并放了一个示例。谢谢你的帮助,真的很感激。哦,那是奇怪的格式数据。您必须先将歌词放入数组中,此函数才能工作。我会更新。更新,查看我的答案中关于代码用法的部分。这里有一些注释解释了我所做的修改
Math.floor(Math.random() * (n - 1)) + 1
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"]
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>";
}