Random loop function - jsonp [duplicate] - javascript

This question already has answers here:
How to randomize (shuffle) a JavaScript array?
(69 answers)
Closed 9 years ago.
I'm trying to randomize a standard loop function. Here's the original loop :
success: function(data) {
for (var i = 0; i < 15; i++) {
$("#myimages").append("<a href='" + data.data[i].link + "' target='_blank' style='float:center;width:300px; height:300px;'><img style='width:20%;' src='" + data.data[i].images.standard_resolution.url + "' /></a>");
}
}
Could anyone help me out. I've had no luck so far.

Here's a fiddle showing 15 numbers being randomized and then looped through: http://jsfiddle.net/pH6Lx/ .
function Shuffle(o) {
for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
};
$(document).ready(function() {
//init array
var testArray = [];
//Fill it with 15 numbers
for(var i=0;i<15;i++)
testArray.push(i);
//Shuffle it ("randomize")
Shuffle(testArray);
//Do something with these numbers
for (var i=0;i<testArray.length;i++) {
$('#random').append(testArray[i]+'<br />');
}
});
In your case this might all happen inside your callback instead.

First, just randomize the array, see: How to randomize (shuffle) a JavaScript array?.
success: function(data) {
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
shuffleArray(data);
Then proceed as before:
for (var i = 0; i < 15; i++) {
$("#myimages").append("<a href='" + data.data[i].link + "' target='_blank' style='float:center;width:300px; height:300px;'><img style='width:20%;' src='" + data.data[i].images.standard_resolution.url + "' /></a>");
}
}

if you are passing a list of images in data.data is possible to do as below
success: function(data) {
var numberOfImages = Math.min( 15, data.data.length ) ; //bug free to don't repeat
var alreadyShow = {}; //to don't repeat
for (var i = 0; i < numberOfImages ; i++) {
do{
var imgIndex = Math.round( Math.random() * ( data.data.length - 1 ) );
}while( alreadyShow[imgIndex] );
alreadyShow[imgIndex] = true;
$("#myimages").append("<a href='" + data.data[imgIndex].link + "' target='_blank' style='float:center;width:300px; height:300px;'><img style='width:20%;' src='" + data.data[imgIndex].images.standard_resolution.url + "' /></a>");
}
}
it's randomize without repeat

Related

Generate random identical object

function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function init(){
var resArr = [];
for (var i = 0; i < 10; i++) {
var obj = new Object();
obj.q = getRandomInt(3,5);
obj.r = getRandomInt(1,10);
resArr.push(obj);
}
var str = '<table border=1><th>Multiplication</th>';
for (var i = 0; i < resArr.length; i++) {
str+='<tr><td>'+resArr[i].q+' * '+resArr[i].r+' = '+(resArr[i].q *resArr[i].r)+'</td></tr>';
}
str += '</table>';
document.getElementById('multiTable').innerHTML = str;
}
init();
<button type="button" name="button" onclick="init()">Refresh</button>
<div id='multiTable'></div>
Here I am generating random object and pushing to an array. I am really stuck how to check that created object is present or not in array.
I want to generate random number to show in multiplication table.
I created a function simply to check for duplicate objects in the array
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function checkDuplicate(arr, obj) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].q == obj.q && arr[i].r == obj.r) {
return true;
break;
}
}
}
function init() {
var resArr = [];
for (var i = 0; i < 10; i++) {
var obj = new Object();
obj.q = getRandomInt(3, 5);
obj.r = getRandomInt(1, 10);
if (!checkDuplicate(resArr, obj)) {
resArr.push(obj);
}
else i--;
}
var str = '<table border=1><th>Multiplication</th>';
for (var i = 0; i < resArr.length; i++) {
str += '<tr><td>' + resArr[i].q + ' * ' + resArr[i].r + ' = ' + (resArr[i].q * resArr[i].r) + '</td></tr>';
}
str += '</table>';
document.getElementById('multiTable').innerHTML = str;
}
init();
<button type="button" name="button" onclick="init()">Refresh</button>
<div id='multiTable'></div>
You could use a hash table and insert all random combination into it after checking if already inserted.
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function init() {
var resArr = [],
hash = {};
for (var i = 0; i < 10; i++) {
var obj = new Object();
do {
obj.q = getRandomInt(3, 5);
obj.r = getRandomInt(1, 10);
} while (hash[[obj.q, obj.r].join('|')])
hash[[obj.q, obj.r].join('|')] = true;
resArr.push(obj);
}
var str = '<table border=1><th>Multiplication</th>';
for (var i = 0; i < resArr.length; i++) {
str += '<tr><td>' + resArr[i].q + ' * ' + resArr[i].r + ' = ' + (resArr[i].q * resArr[i].r) + '</td></tr>';
}
str += '</table>';
document.getElementById('multiTable').innerHTML = str;
}
init();
<button type="button" name="button" onclick="init()">Refresh</button>
<div id='multiTable'></div>
Try with Array#filter() method .check the matched object length .And change with while loop for always give a 10 result's
updated
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function init() {
var resArr = [];
var i=0;
while (true) {
var obj = new Object();
obj.q = getRandomInt(3, 5);
obj.r = getRandomInt(1, 10);
if(!resArr.filter(a=> a.q == obj.q && a.r == obj.r).length>0){
resArr.push(obj);
i++;
}
if(i == 10){
break;
}
}
var str = '<table border=1><th>Multiplication</th>';
for (var i = 0; i < resArr.length; i++) {
str += '<tr><td>' + resArr[i].q + ' * ' + resArr[i].r + ' = ' + (resArr[i].q * resArr[i].r) + '</td></tr>';
}
str += '</table>';
document.getElementById('multiTable').innerHTML = str;
}
init();
<button type="button" name="button" onclick="init()">Refresh</button>
<div id='multiTable'></div>

Make a selectable html table with objects as values

I am been trying to create a html table that is populated by objects.
The table was supposed to be selectable by row (via hover), when the row was hovered over a function ran.
The table headers are in an array:
var topTitles = ["Type","Origin","Destination","T","A","G"];
all the data are sitting inside arrays,
var Type = [];
var Origin = [];
var Destination = [];
var T = [];
var A = [];
var G = [];
I tried to modify an example piece of code, but it was very difficult to conceptualize it and place it into a programatic solution. What is an easy way to map such data directly into a interactive table.
function createTable() {
var table = document.getElementById('matrix');
var tr = addRow(table);
for (var j = 0; j < 6; j++) {
var td = addElement(tr);
td.setAttribute("class", "headers");
td.appendChild(document.createTextNode(topTitles[j]));
}
for (var i = 0; i < origins.length; i++) {
var tr = addRow(table);
var td = addElement(tr);
td.setAttribute("class", "origin");
td.appendChild(document.createTextNode(mode[i]));
for (var j = 0; j < topTitles.length; j++) {
var td = addElement(tr, 'element-' + i + '-' + j);
td.onmouseover = getRouteFunction(i,j);
td.onclick = getRouteFunction(i,j);
}
}
}
function populateTable(rows) {
for (var i = 0; i < rows.length; i++) {
for (var j = 0; j < rows[i].elements.length; j++) {
var distance = rows[i].elements[j].distance.text;
var duration = rows[i].elements[j].duration.text;
var td = document.getElementById('element-' + i + '-' + j);
td.innerHTML = origins[i] + "<br/>" + destinations[j];
}
}
}
if (highlightedCell) {
highlightedCell.style.backgroundColor="#ffffff";
}
highlightedCell = document.getElementById('element-' + i + '-' + j);
highlightedCell.style.backgroundColor="#e0ffff";
showValues();
}
This is probably the easiest way I could think of building the table without changing your data structure and make it very clear where all the data is coming from. It is defiantly not the best code, but it should work for your situation.
CodePen
var topTitles = ["Type","Origin","Destination","T","A","G"];
var Type = ["Type1", "type2", "type3"];
var Origin = ["Origin1", "origin2", "origin3"];
var Destination = ["Destination1", "Destination2", "dest3"];
var T = ["t1", "t2","T3"];
var A = ["steaksauce", "a2", "a3"];
var G = ["G1", "G2", "G3"];
var appendString = [];
for(var i =0; i < topTitles.length; i++){
if(!i){
appendString.push("<tr><td>" + topTitles[i] + "</td>");
}
else if(i === topTitles.length -1){
appendString.push("<td>" + topTitles[i] + "</td></tr>");
}
else{
appendString.push("<td>" + topTitles[i] + "</td>");
}
}
for(var i =0; i < Type.length; i++){
appendString.push("<tr><td>" + Type[i] + "</td><td>" + Origin[i] + "</td><td>" + Destination[i] + "</td><td>" + T[i] + "</td><td>" + A[i] + "</td><td>" + G[i] + "</td></tr>");
}
var table = document.getElementById('table');
table.innerHTML = appendString.join('');

JavaScript NaN with HTML

I'm trying to create a small maths game with the code below, however I keep getting Not-A-Number error everytime the prompt comes up. i'm not entirely sure what the problem is. I have tried to round the number but it doesn't help the situation. Could someone point me in the right direction?
function start() {
// define questions
var question = [];
// define answers
var answer = [];
// store user input
var input = [];
var score = 0;
// when the user enters their answer it is stored by input for every prompt
for(var i = 0; i < 10; i++) {
var randNum = Math.floor(Math.random() * 100);
var operator = [ '+', '-', '*', '/' ];
var ops = [Math.floor(Math.random() * operator.length)];
question[i] = randNum + ops[operator] + randNum;
answer[i] = randNum + ops[operator] + randNum;
input[i] = prompt(question[i]);
}
// check the answer against the stored answer, display one of either from if statement
for(var i = 0; i < answer.length; i++) {
if (answer[i] == input[i]) {
var outputResult = document.getElementById("write");
outputResult.innerHTML += "<p class = corr>Question " + (i+1) + " is correct.</p>";
} else {
outputResult.innerHTML += "<p class = incorr>Question " + (i+1) + " is incorrect. The answer should have been " + answer[i] + ".</p>";
}
}
}
<header>
<h1>Maths Game!</h1>
</header>
<button onclick="start()">Start</button> <!-- start game -->
<div id="write">
</div>
<div class="score"></div>
</div>
You reference the operator array incorrectly. Try this:
var operator = ['+', '-', '*', '/'];
var ops = Math.floor(Math.random() * operator.length);
question[i] = randNum + operator[ops] + randNum;
answer[i] = eval(question[i]);
input[i] = prompt(question[i]);
These two lines create NaN in each index of question/answer ARRAYs:
question[i] = randNum + ops[operator] + randNum;
answer[i] = randNum + ops[operator] + randNum;
Because:
ops[operator]
is not a Number;

Javascript event not defined in Firefox

This has been asked before but I'm still struggling to wrap my head around how to fix the error in my case. I'm new to learning Javascript/jQuery. Firefox gives an error "ReferenceError: getFirstArr is not defined". I have a simplified script of what I'm trying to do here JSFiddle (to make it work, select a year button first before a month button).
The culprit seems to be the getFirstArr(videos[i]) line 28. I really don't even know what to try since my code seems correct. It works in Safari, Chrome and IE. Firefox is the odd man out. Here's a snippet of the on click event where the problem is.
$('.campbutton').on('click', function () {
camp = $(this).attr('id');
$('.campbutton').removeClass('green');
$(this).addClass('green');
$('#searcharea').html('<table></table>');
var campyear = camp + year;
var count = 1;
var noResultCount = 0;
for (i = 0; i < videos.length; i++) {
for (j = 0; j < 5; j++) {
getFirstArr(videos[i]); // Firefox doesn't like this line
function getFirstArr(video) { // prints the the array where a match is found
The JSFiddle will have the whole code. So my question is, why is Firefox not accepting the function call, and what needs to be changed? Any help or hints are appreciated (btw, I'm still working on getting the correct table tags to format the output correctly so the videos don't just stack on top of themselves).
Edit: The specific problem Firefox has is when the camp button is clicked, no videos load in the div. The other button events are fine.
Here's the entire code in question:
var videos = [ ["string1A", "string1B", "string1C"], ["string2A", "String2B", String2C"] ];
var camp = "";
var year = "";
$('#searcharea').html('select a year button first');
$('.yearbutton').on('click', function () {
year = $(this).attr('id');
$('.yearbutton').removeClass('green');
$(this).addClass('green');
});
$('.campbutton').on('click', function () {
camp = $(this).attr('id');
$('.campbutton').removeClass('green');
$(this).addClass('green');
$('#searcharea').html('<table></table>');
var campyear = camp + year;
var count = 1;
var noResultCount = 0;
for (i = 0; i < videos.length; i++) {
for (j = 0; j < 5; j++) {
getFirstArr(videos[i]);
function getFirstArr(video) {
if (campyear === video[j]) {
var pos = video.indexOf(video[j]);
$('#searcharea').append('<tr><td>' + video[(pos - pos)] + '</td>' + '<td>' + 'Composer: ' + video[(pos -pos) + 1] + '<br>' + 'Player: ' + video[(pos - pos) + 2] + '<br>' + 'Piece: ' + video[(pos - pos) + 3] + '</td>');
}
else noResultCount++;
if (campyear === video[j] && count % 3 === 0 && j === 4)
$('#searcharea').append('</tr><tr>');
if (i === videos.lenght && j === 4)
$('#searcharea').append('</table>');
}
}
count++;
}
if (noResultCount === videos.length * 5)
$('#searcharea').html("No results found");
});
http://jsfiddle.net/3ncc5xdx/123/
Here i have moved your function to outside the loop like so, I think it works, unless I misunderstood what the issue is:
$('.campbutton').on('click', function () {
camp = $(this).attr('id');
$('.campbutton').removeClass('green');
$(this).addClass('green');
$('#searcharea').html('<table></table>');
var campyear = camp + year;
var count = 1;
var noResultCount = 0;
function getFirstArr(video) {
if (campyear === video[j]) {
var pos = video.indexOf(video[j]);
$('#searcharea').append('<tr><td>' + video[(pos - pos)] + '</td>' + '<td>' + 'Composer: ' + video[(pos -pos) + 1] + '<br>' + 'Player: ' + video[(pos - pos) + 2] + '<br>' + 'Piece: ' + video[(pos - pos) + 3] + '</td>');
}
else noResultCount++;
if (campyear === video[j] && count % 3 === 0 && j === 4)
$('#searcharea').append('</tr><tr>');
if (i === videos.lenght && j === 4)
$('#searcharea').append('</table>');
}
for (i = 0; i < videos.length; i++) {
for (j = 0; j < 5; j++) {
getFirstArr(videos[i]);
}
count++;
}
if (noResultCount === videos.length * 5)
$('#searcharea').html("No results found");
});
So the reason that it works is that the function is now declared before it is used once. Also, its now only declared once rather than again and again in your loop. It probably works in Chrome because Chrome is pretty smart and figuring our what you were implying – but Firefox will need a slightly more strict approach.

Shuffle select menu options

Basically I have 5 words picked out of an array (English Words) And I pick 1 French word out of another array which the user then has to guess what that french word means in english.
At the moment I am adding the Correct English Answer to the end of the select menu because I don't know how to add it inbetween the others randomly, or more so to shuffle the select menus options
I Have added my JSfiddle below, It is an exact replica. You will realise that the bottom option is always correct! (The user will begin to know the pattern). I've also had to add my javascript below to be able to post the JSfiddle
http://jsfiddle.net/jamesw1/w8p7b6p3/5/
var
RanNumbers = new Array(6),
foreignWords = ['un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix-sept', 'dix-huit', 'dix-neuf', 'vingt', 'vingt et un', 'vingt-deux', 'vingt-trois', 'vingt-quatre', 'vingt-cinq', 'vingt-six', 'vingt-sept', 'vingt-huit', 'vingt-neuf', 'trente'],
translate = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen', 'twenty', 'twenty-one', 'twenty-two', 'twenty-three', 'twenty-four', 'twenty-five', 'twenty-six', 'twenty-seven', 'twenty-eight', 'twenty-nine', 'thirty'],
number = Math.floor((Math.random() * 30)),
output = '',
correctAns = translate[number];
//Generate random numbers to pick the available answers
function wordGen() {
for (var h = 0; h < RanNumbers.length; h++) {
var temp = 0;
do {
temp = Math.floor(Math.random() * 30);
} while (RanNumbers.indexOf(temp) > -1);
RanNumbers[h] = temp;
}
}
//Call the previous function
wordGen();
//Create dynamic select menu
document.getElementById('generatedWord').textContent = foreignWords[number];
var guess = "<select name='guesses' id='guesses'>";
for (var i = 0; i < 6; i++) {
guess += "<option value='" + i + "'>" + translate[RanNumbers[i]] + "</option>";
}
guess += '<option value="6">' + correctAns + '</option>';
guess += "</select>";
document.getElementById('output').innerHTML = guess;
numGuessed = document.getElementById('guesses').value;
function arrayValueIndex(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === val) {
return i;
}
}
return false;
}
var numGames = 5;
var numGuesses = 1;
var correct = 0;
var wrong = 0;
var prevNumber;
//On click, gather correct and wrong answers, create new numbers, create new options, create new word.
document.getElementById('submitAns').onclick = function () {
prevNumber = number;
number = Math.floor((Math.random() * 30)),
output = '',
correctAns = translate[number];
document.getElementById('numGuess').innerHTML = "Question #" + numGuesses;
var
genWord = document.getElementById('generatedWord').textContent,
select = document.getElementById('guesses'),
selectedText = select.options[select.selectedIndex].text;
prevNumber === arrayValueIndex(translate, selectedText) ? correct++ : wrong++;
//Re doing the function, getting new values...
function wordGen() {
for (var j = 0; j < RanNumbers.length; j++) {
var temp = 0;
do {
temp = Math.floor(Math.random() * 30);
} while (RanNumbers.indexOf(temp) > -1);
RanNumbers[j] = temp;
}
}
//Call the previous function
wordGen();
//Create dynamic select menu
document.getElementById('generatedWord').textContent = foreignWords[number];
var guess = "<select name='guesses' id='guesses'>";
for (var i = 1; i <= 6; i++) {
guess += "<option value='" + i + "'>" + translate[RanNumbers[i]] + "</option>";
}
guess += '<option value="6">' + correctAns + '</option>';
guess += "</select>";
document.getElementById('output').innerHTML = guess;
numGuessed = document.getElementById('guesses').value;
function arrayValueIndex(arr, val) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === val) {
return i;
}
}
return false;
}
//Checking of the answers below, Accumilating correct and wrong answer.
numGuesses++;
if (numGuesses == 6) {
document.getElementById('generatedWord').innerHTML = "<span style='font-size:12px;color:red';>Please click for a new game when ready!</span><br /><p>You got " + wrong + " questions wrong " + "<br />You got " + correct + " questions correct";
$('#submitAns').hide();
}
};
You should use Math.random method, it would be something like this:
var correctAnswerIndex = Math.floor(Math.random() * 7); //gives random number between 0-6
for (var i = 1; i <= 6; i++) {
if(i == correctAnswerIndex)
guess += '<option value="'+i+'">' + correctAns + '</option>';
else
guess += "<option value='" + i + "'>" + translate[RanNumbers[i]] + "</option>";
}
you will need just to adjust else statement, as RanNumbers may not have 6 items. So maybe to introduce additional counter that would be used insead of i. (something like translate[RanNumbers[counter++]])

Categories