PDA

View Full Version : Displaying random text without repeating the content



kimash
01-26-2011, 12:58 AM
I'm using the script below in a custom HTML to generate a random line of text (not with the text shown here). This works fine BUT; I want it to go randomly through the WHOLE list without repeating lines that already have been printed. As it is now, a line of text might be printed several times in a row, which is a little annoying. I'm using a refresh button for generating a new line of text.

Alternatively, How can I just make it display in the order shown and just re-arrange the content so it seems random to the user? Random would the best though...

Any ideas?? : )


<script language="JavaScript">
<!--
var r_text = new Array ();
r_text[0] = "All the leaves are brown";
r_text[1] = "And the sky is grey";
r_text[2] = "I've been for a walk";
r_text[3] = "On a winter's day";
r_text[4] = "I'd be safe and warm";
r_text[5] = "If I was in L.A.";
r_text[6] = "California dreaming, On such a winter's day";
var i = Math.floor(7*Math.random())

document.write(r_text[i]);

//-->
</script>

Philip M
01-26-2011, 07:35 AM
Rather than select a quotation at random from the array, you should shuffle the quotations into random order, in this way they will not repeat.



<span id = "randomText"></span><br>

<script type = "text/javascript">

shuffle = function(v){
for(var j, x, i = v.length; i; j = parseInt(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);
return v;
}

var r_text = new Array ();
r_text[0] = "All the leaves are brown";
r_text[1] = "And the sky is grey";
r_text[2] = "I've been for a walk";
r_text[3] = "On a winter's day";
r_text[4] = "I'd be safe and warm";
r_text[5] = "If I was in L.A.";
r_text[6] = "California dreaming, On such a winter's day";

var shf = shuffle(r_text);
//alert (r_text);

var index = 0;
function show() {
document.getElementById("randomText").innerHTML = r_text[index];
index ++;
if (index > r_text.length-1) {index = 0; shuffle(r_text); alert (r_text)} // start again
setTimeout("show()",2000); // 2 seconds delay
}

show();

</script>


<script language=javascript> is long deprecated and obsolete. Use <script type = "text/javascript"> instead.
The <!-- and //--> comment (hiding) tags have not been necessary since IE3 (i.e. since September 1997). If you see these in some published script it is a warning that you are looking at ancient and perhaps unreliable code.



Drogba has had malaria, so he is not fit for whatever reason .... Sky TV

kimash
01-26-2011, 12:14 PM
okay! Thanks.
But then.. How can I make the content display on click? Rather than it? shuffling automatically

Philip M
01-26-2011, 12:44 PM
okay! Thanks.
But then.. How can I make the content display on click? Rather than it? shuffling automatically

You ought to be able to work that out for yourself.

<input type = "button" id = "button1" value = "Click to display a new quotation" onclick = "show()">
and delete the line setTimeout("show()",2000); // 2 seconds delay

siberia-man
01-26-2011, 02:01 PM
shuffle = function(v){
for(var j, x, i = v.length; i; j = parseInt(Math.random() * i), x = v[--i], v[i] = v[j], v[j] = x);
return v;
}




Hi Philip,

Are you sure that your function should narrow the range of possible values in j at the end of iterations? Just check values of i and j:


for (var j, i = v.length; i; j = parseInt(Math.random() * i), --i, alert(i, j));


Maybe you meant the following code:


for (var j, x, i = n = v.length; i; j = parseInt(Math.random() * n), x = v[--i], v[i] = v[j], v[j] = x);


And as a conclusion... Below are my suggestions.

1. the simplest but the most time expensive



Array.prototype.shuffle = function()
{
return this.sort(function()
{
return Math.random() - 0.5;
});
};

alert([1, 2, 3, 4, 5].shuffle());


2. the shortest in time although the wordy


Array.prototype.shuffle = function()
{
var n = this.length;
var j;
var t;
for (var i = 1; i < n; i++) {
j = Math.floor(Math.random() * n);

t = this[i];
this[i] = this[j];
this[j] = t;
}
return this;
};

alert([1, 2, 3, 4, 5].shuffle());

Philip M
01-26-2011, 04:40 PM
Noted. :) I have not noticed any problems with my code,but your suggested improvement is appreciated, although as far as I can see it results in exactly the same. :)

I don't think that these days time of execution matters in 99% of cases. It would if the array was very large, of course.

There is a missing closing bracket ) in your code 1.

return Math.random() - 0.5;
};
)
};

siberia-man
01-26-2011, 04:50 PM
There is a missing closing bracket ) in your code 1.

return Math.random() - 0.5;
};
)
};
Yes. Thank for notice. I have fixed this one in my previous post.


I don't think that these days time of execution matters in 99% of cases. It would if the array was very large, of course.

Confirm this. For large arrays it can be seen sufficient impact on the performance.

Clownie
04-20-2012, 06:34 PM
Hi,
Just registered to this forum... hope I'm ok with bumping this old thread, but I really need help on this, and from Philip M...

Here's the thing... I'm not a coder at all, just playing around for many years... I developed this website, about quotes: http://keep-quiet.com and using random javascript scripts, and the codes given by Philip are exactly what I'm looking for, for having random selection of arrays, WITHOUT repeat. Here's an example so far with this: http://keep-quiet.com/norepeat.html

It works great, when you call the script by clicking the "test 1" link, it will shuffle the 7 arrays, then will display them one by one, with no repeat, at each click.


<script type = "text/javascript">
shuffle = function(v){
for (var j, x, i = n = v.length; i; j = parseInt(Math.random() * n), x = v[--i], v[i] = v[j], v[j] = x);
return v;
}

var arQAnna = new Array ();
arQAnna[0] = "a";
arQAnna[1] = "b";
arQAnna[2] = "c";
arQAnna[3] = "d";
arQAnna[4] = "e";
arQAnna[5] = "f";
arQAnna[6] = "g";


var shf = shuffle(arQAnna);

var inTemp = 0;

function randomAnna() {
document.getElementById("qotmo").innerHTML = arQAnna[inTemp];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = intQuoteIndex;
document.getElementById("shuforder").innerHTML = shf;

inTemp++;

if (inTemp > arQAnna.length-1) {
inTemp = 0;
shuffle(arQAnna);
}
}

</script>

<a href="javascript:;" onclick="randomAnna();">test 1</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="shuforder"></span>


But, what I want, is to be able to get the original id of the array. With Philip script, all I can have is an id of the array after they have been shuffled. For example, on shuffling, the first array to be displayed could be the id=3 which will display 'd', but when I try to get the array id, it gives me 0 instead of 3 as it's the first array which comes after the shuffling. I hope it's clear enough, I'm not english and it's a bit hard to explain (the example page should make it clearer though...).

Another question I have is this: would it be ok to use this shuffle script with very large number of arrays (+1000)? If not, is there other methods I could achieve this?

Thanks a lot... and sorry if these are dumb questions for advanced coders...

Clownie

Philip M
04-20-2012, 06:48 PM
Hi,
But, what I want, is to be able to get the original id of the array. With Philip script, all I can have is an id of the array after they have been shuffled. For example, on shuffling, the first array to be displayed could be the id=3 which will display 'd', but when I try to get the array id, it gives me 0 instead of 3 as it's the first array which comes after the shuffling. I hope it's clear enough, I'm not english and it's a bit hard to explain (the example page should make it clearer though...).

Another question I have is this: would it be ok to use this shuffle script with very large number of arrays (+1000)? If not, is there other methods I could achieve this?

Thanks a lot... and sorry if these are dumb questions for advanced coders...

Clownie

I don't really understand, there are not 7 arrays but one array with 7 elements. But if you want to capture a value before shuffling simply copy it to another variable.

The shuffle script will work with any number of elements in the array (subject to overall capacity constraints). But for 1000 elements you might prefer to use siberia-man's most efficient code in Post #5. But if you want an unbiased shuffle use:-



Array.prototype.shuffle = function() {
var s = [];
while (this.length) s.push(this.splice(Math.random() * this.length, 1));
while (s.length) this.push(s.pop());
return this;
}

xelawho
04-20-2012, 07:35 PM
I'm a little confused, too, but maybe this has some use...



<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

function shuffle()
{
return (Math.round(Math.random())-0.5);
}

var arQAnna = ["a","b","c","d","e","f","g"]
var orString=arQAnna.toString().replace(/,/g,"");
arQAnna.sort(shuffle);

var inTemp = 0;

function randomAnna() {
document.getElementById("qotmo").innerHTML = "random letter is: "+arQAnna[inTemp];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "letter is now at position: "+intQuoteIndex;
document.getElementById("shuforder").innerHTML = "array is now: "+arQAnna.toString();
document.getElementById("orig").innerHTML = "original position: "+orString.indexOf(arQAnna[inTemp]);
inTemp++;

if (inTemp > arQAnna.length-1) {
inTemp = 0;
arQAnna.sort(shuffle);
}
}

</script>

<a href="#" onclick="randomAnna();return false">test 1</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="orig"></span><br><br/>
<span id="shuforder"></span>
</body>
</html>

Clownie
04-20-2012, 08:00 PM
Hi Philip,
Thanks for the reply! Sorry, of course, I meant 'elements' not 'arrays'.... and xelawho managed to get what I was so difficultly trying to say... yes, I wanted to have the origin element id...

Thanks for the shuffle script, will try it...

Clownie
04-20-2012, 08:10 PM
Hi xelawho, yes, this is exactly what I was asking, to be able to get the original element position.

Now, I have a small problem, as the way you define the array
var arQAnna = ["a","b","c","d","e","f","g"] is different than how it is define in my script
arQAnna[0] = "a";
arQAnna[1] = "b";
arQAnna[2] = "c";
arQAnna[3] = "d";
arQAnna[4] = "e";
arQAnna[5] = "f";
arQAnna[6] = "g";

I know, this is kinda lame (really, I'm a poor amateur coder), but could you please show me how to use your scripting with the definition of arrays like the one I used? The reason is that in some of the scripts I use, there are a lot of elements, and the elements are sometimes very large (long quotations) and there other variables added to each element... ex:
arQAnna[0]=imganna + "Tayumanuvar, a Tamil saint whom Bhagavan often quoted, wrote in one of his poems: 'My Guru merely told me that I am consciousness. Having heard this, I held onto consciousness. What he told me was just one sentence, but I cannot describe the bliss I attained from holding onto that one simple sentence. Through that one sentence I attained a peace and a happiness that can never be explained in words'." + anna;

And would your script work with an array of +1000 elements? Otherwise, I will try to adapt it with what Philip shared.

Thanks in advance! It's really appreciated as I spent a long time on the web trying to find infos in order to manage it myself, but with no result....

xelawho
04-20-2012, 08:32 PM
there's no difference (as far as I can tell anyway). this:


var arQAnna = ["a","b","c","d","e","f","g"]


is just a quicker, easier way of writing this:


var arQAnna = new Array ();
arQAnna[0] = "a";
arQAnna[1] = "b";
arQAnna[2] = "c";
arQAnna[3] = "d";
arQAnna[4] = "e";
arQAnna[5] = "f";
arQAnna[6] = "g";

if for some reason you wanted to take the numbers out of sequence or do something else fancy it may be a different story. but for your purposes, they're the same. If all you are worried about is layout in your code, javascript ignores whitespace, so you could write your array like this:


var arQAnna = ["In the same way, mind is just a Self-inflicted area of darkness in which the light of the Self has been deliberately shut out.",
"The mind and the body are both inert. Any energy or peace you experience can only come from the Self. Drop the identification with the body. These experiences are making you too body-conscious. Just be aware of the Self and try to pay as little attention as possible to the body. The Self is pure energy, pure power. Hold onto that. ",
"If you can give up duality, Brahman alone remains, and you know yourself to be that Brahman, but to make this discovery continuous meditation is required. Don't allocate periods of time for this. Don't regard it as something you do when you sit with your eyes closed. This meditation has to be continuous. Do it while eating, walking and even talking. It has to be continued all the time.",
"Remember that nothing that happens in the mind is 'you', and none of it is your business. You don't have to worry about the thoughts that rise up inside you. It is enough that you remember that the thoughts are not you.",
"Tayumanuvar, a Tamil saint whom Bhagavan often quoted, wrote in one of his poems: 'My Guru merely told me that I am consciousness. Having heard this, I held onto consciousness. What he told me was just one sentence, but I cannot describe the bliss I attained from holding onto that one simple sentence. Through that one sentence I attained a peace and a happiness that can never be explained in words.'",
"In every moment you only have one real choice: to be aware of the Self or to identify with the body and the mind. ",
"You have to keep up the enquiry, 'To whom is this happening?' all the time. If you are having trouble remind yourself, 'This is just happening on the surface of my mind. I am not this mind or the wandering thoughts.' Then go back into enquiry 'Who am I?'. By doing this you will penetrate deeper and deeper and become detached from the mind. This will only come about after you have made an intense effort."]

Just remember to enclose each quote in double quotes and each quote within the quote in single quotation marks, and to put a comma at the end of each one, except for the last one.

I assume that the code will work with 1000 elements, although I can't say I've tried it. I don't know enough to say which approach would be more efficient. The same array will work for all versions posted, though - why not test them all out?

c1lonewolf
04-20-2012, 08:47 PM
@Philip M

I don't think that these days time of execution matters in 99% of cases. It would if the array was very large, of course.

A while back a made a js function based on, I guess C programming, designed to search for items in a mega sized datatable. The C programming used a method of checking entries from 1 to say 100, then switched to checking entries from datatable length - 100. They stated that most newer items that are searched for are posted in the lower part of the datatable and using this back & forth method retrieved information faster than running a loop in one direction. So if you implemented that methodolgy into your shuffle function do you think it would save time on larger arrays?

Note the function I built was for a search of my dataArray styles where I sorted data according column. I only used it for one project hehehe. Just wondering...

Clownie
04-20-2012, 09:55 PM
Thanks very much xelawho!

But as I said, I'm really a newbie.... :)

Whether I use both methods to define the array (I did some tests), I don't know what to do with this piece of code so it works...
var orString=arQAnna.toString().replace(/,/g,"");

For example, what should be changed in it, so this (see the new array with elements 'one', 'two' etc....) can work?


<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

function shuffle()
{
return (Math.round(Math.random())-0.5);
}


var arQAnna = new Array ();
arQAnna[0] = "zero";
arQAnna[1] = "one";
arQAnna[2] = "two";
arQAnna[3] = "three";
arQAnna[4] = "four";
arQAnna[5] = "five";
arQAnna[6] = "six";
arQAnna[7] = "seven";
arQAnna[8] = "eight";
arQAnna[9] = "nine";
arQAnna[10] = "ten";

// what should change in the line below?
var orString=arQAnna.toString().replace(/,/g,"");
arQAnna.sort(shuffle);

var inTemp = 0;

function randomAnna() {
document.getElementById("qotmo").innerHTML = "random element is: "+arQAnna[inTemp];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "element is now at position: "+intQuoteIndex;
document.getElementById("shuforder").innerHTML = "array is now: "+arQAnna.toString();
document.getElementById("orig").innerHTML = "original position: "+orString.indexOf(arQAnna[inTemp]);
inTemp++;

if (inTemp > arQAnna.length-1) {
inTemp = 0;
arQAnna.sort(shuffle);
}
}

</script>

<a href="#" onclick="randomAnna();return false">test 1</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="orig"></span><br><br/>
<span id="shuforder"></span>
</body>
</html>

Again, sorry if this so trivial for you... and thanks again for the help.

xelawho
04-20-2012, 10:04 PM
yeah, I see the problem - it worked fine for one-letter elements because indexOf counts the letters in the string :o

it's not a good code for what you want to do, anyway... replacing the commas like that will only mess up your array. I'm going to have to rethink it (or maybe somebody else can :D)...

Clownie
04-20-2012, 10:23 PM
But if you want an unbiased shuffle use:-

Array.prototype.shuffle = function() {
var s = [];
while (this.length) s.push(this.splice(Math.random() * this.length, 1));
while (s.length) this.push(s.pop());
return this;
}

Philip, thanks again... It's working great... so may be now I'm more clear, with the same code, how can I grab the original position of the elements, after being shuffled? For example, after the shuffle, if the first element of the array is 'five', the position would be 1, but I'd like to get also it's original position which is 5 (is it really more clear??? ;)

http://keep-quiet.com/norepeat.html


<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

shuffle = function() {
var s = [];
while (arQAnna.length) s.push(arQAnna.splice(Math.random() * arQAnna.length, 1));
while (s.length) arQAnna.push(s.pop());
return arQAnna;
}

var arQAnna = new Array ();
arQAnna[0] = "zero";
arQAnna[1] = "one";
arQAnna[2] = "two";
arQAnna[3] = "three";
arQAnna[4] = "four";
arQAnna[5] = "five";
arQAnna[6] = "six";
arQAnna[7] = "seven";


var shf = shuffle(arQAnna);

var inTemp = 0;

function randomAnna() {
document.getElementById("qotmo").innerHTML = "random element is: "+arQAnna[inTemp];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "element is now at position: "+intQuoteIndex;
document.getElementById("shuforder").innerHTML = "array is now at: "+shf;
inTemp++;

if (inTemp > arQAnna.length-1) {
inTemp = 0;
shuffle(arQAnna);
}
}

</script>

<a href="javascript:;" onclick="randomAnna();">test 1</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="shuforder"></span>

</body>
</html>

xelawho
04-20-2012, 11:15 PM
the problem with shuffling the array (or the ways that I know to do it anyway) is that it changes the original array, so keeping a reference to how it was originally basically means making a copy of it.

But you can keep the original array and make a parallel array of numbers which you can then randomize and use to display random elements of the original, untouched array.

If on the other hand you just want to display random quotes from an array, we are way overthinking this. Here's one way, anyway...



<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

function shuffle()
{
return (Math.round(Math.random())-0.5);
}

var arQAnna = new Array ();
arQAnna[0] = "zero";
arQAnna[1] = "one";
arQAnna[2] = "two";
arQAnna[3] = "three";
arQAnna[4] = "four";
arQAnna[5] = "five";
arQAnna[6] = "six";
arQAnna[7] = "seven";
arQAnna[8] = "eight";
arQAnna[9] = "nine";
arQAnna[10] = "ten";

var randArr=[];
for(var x=0;x<arQAnna.length;x++){
randArr.push(x)
}

randArr.sort(shuffle);

var inTemp = 0;

function randomAnna() {
var str=""
var quote=arQAnna[randArr[inTemp]];
document.getElementById("qotmo").innerHTML = "random element is: "+arQAnna[randArr[inTemp]];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "element is now at position: "+intQuoteIndex;
for(var x=0;x<arQAnna.length;x++){
if (arQAnna[x]==quote){
document.getElementById("orig").innerHTML = "original position: "+x;
break;
}
}

for(var x=0;x<randArr.length;x++){
str+=arQAnna[randArr[x]]+", ";
}

document.getElementById("shuforder").innerHTML = "array is now: "+str;

inTemp++;

if (inTemp > arQAnna.length-1) {
inTemp = 0;
randArr.sort(shuffle);
}
}
</script>

<a href="#" onclick="randomAnna();return false">test 1</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="orig"></span><br><br/>
<span id="shuforder"></span>
</body>
</html>

Clownie
04-20-2012, 11:43 PM
xelawho, thank you!!!!!!! Works great... have to test it in real condition (lots of quotes/objects in the array)... but it is doing the job very nicely!

And no, it's not overthought, as I need to keep track of the original index elements (which are quotes) as I'm playing with it a lot (for example, using it to build a unique url to access the quote with this unique index... see http://keep-quiet.com and one example http://keep-quiet.com/?q=141&w=m1)

Thanks for your patience! I'm really a beginner...

Old Pedant
04-21-2012, 12:12 AM
I have to stick my stupid neck into this.


<script type="text/javascript">
var messages = [
[0,"An apple a day keeps the doctor at bay"],
[1,"When in the course of inhuman events"],
[2,"All's well that ends swell"],
[3,"Never look a gift horse in the spleen"]
];

messages.sort( function() { return Math.random() - 0.5; } );

function showOne( n )
{
var msg = messages[n];
document.getElementById("whatever").innerHTML =
"Original message " + msg[0] + " is " + msg[1];
}


In other words, keep track of the original element number by the simple expedient of numbering the messages and keeping the numbers throughout the shuffle.

Old Pedant
04-21-2012, 12:16 AM
Or another way:


<script type="text/javascript">
var messages = [
"An apple a day keeps the doctor at bay",
"When in the course of inhuman events",
"All's well that ends swell",
"Never look a gift horse in the spleen"
];
var numbers = [];
for ( var n = 0; n < messages.length; ++n )
{
numbers[n] = n;
}
numbers.sort( function() { return Math.random() - 0.5; } );

function showOne( n )
{
var num = numbers[n];
document.getElementById("whatever").innerHTML =
"Original message " + num + " is " + messages[num];
}

That is, shulffle only the array *INDEXES* of the original array.

xelawho
04-21-2012, 12:23 AM
I have to stick my stupid neck into this.

what took you so long? ;)

Old Pedant
04-21-2012, 12:26 AM
I saw the thread was over a year old and thought it was somebody just rehashing old stuff. Finally got curious enough, since there were so many posts.

Clownie
04-21-2012, 02:53 PM
xelawho... Your script works perfectly (post #18)... I'm implementing it in my scripts... now, if I may ask for another bit of help...

What would be the code for another function, a kind of 'previous' function, that would recall the last object/quote of the random shuffled array?

Sometimes, you click the random function link ('test 1' link in the example) and you realize you'd like to read again the previous quote... for example, from a new shuffle, you get/read first the quote 'three', then 'eight', then 'five'... and I'd need a function (that I'll call from a "Previous" href link) that would recall the previous quote/element of the shuffle, the 'eight' one in my example (in the 'qotmo' span)... (this function would also still get/print in the 'orig' span, the original index of the quote 'eight', which is 8).

Hope I'm clear enough... Thanks anyways.

jmrker
04-21-2012, 03:18 PM
How many "previous" quotes do you need to maintain?

If only one, not a problem ...
when quote is updated, save the previous one before changing.

If multiple "previous" quotes, save the current previous quote into a second array that overwrites as it overflows after a certain pre-determined size.

xelawho
04-21-2012, 03:35 PM
... or move the inTemp counter up or down depending on the link clicked...



<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

function shuffle()
{
return (Math.round(Math.random())-0.5);
}

var arQAnna = new Array ();
arQAnna[0] = "zero";
arQAnna[1] = "one";
arQAnna[2] = "two";
arQAnna[3] = "three";
arQAnna[4] = "four";
arQAnna[5] = "five";
arQAnna[6] = "six";
arQAnna[7] = "seven";
arQAnna[8] = "eight";
arQAnna[9] = "nine";
arQAnna[10] = "ten";

var randArr=[];
for(var x=0;x<arQAnna.length;x++){
randArr.push(x)
}

randArr.sort(shuffle);

var inTemp = 0;

function randomAnna(dir) {

inTemp=dir=="up"?inTemp+1:inTemp-1;

if (inTemp==arQAnna.length) {
inTemp = 0;
randArr.sort(shuffle);
}

if (inTemp<0) {
inTemp++;
return};

var str=""
var quote=randArr[inTemp];
document.getElementById("qotmo").innerHTML = "random element is: "+arQAnna[quote];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "element is now at position: "+intQuoteIndex;
document.getElementById("orig").innerHTML = "original position: "+quote;

for(var x=0;x<randArr.length;x++){
str+=arQAnna[randArr[x]]+", ";
}
document.getElementById("shuforder").innerHTML = "array is now: "+str;
}

</script>

<a href="#" onclick="randomAnna('up');return false">test 1</a><br/><br/>
<a href="#" onclick="randomAnna('dn');return false">Previous</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="orig"></span><br><br/>
<span id="shuforder"></span>
</body>
</html>

jmrker
04-21-2012, 04:25 PM
Good idea.

Alternate solution for only one previous message.


<!DOCTYPE html>
<html>
<head>
<title> Quote of the Day </title>
<script type="text/javascript">
// Modified from: http://www.codingforums.com/showthread.php?t=216342&page=2

function showOne( n ) {
var num = numbers[n];
var tstr = '';
// tstr += "Original message " + n + ' at '+ num + " is:<br>";
tstr += messages[num];
// alert('Last, Current, pointer quote: '+LastQuote+' : '+Quotenum+' : '+num);
document.getElementById("whatever").innerHTML = tstr;
}
function showNext() {
LastQuote = Quotenum;
Quotenum = (Quotenum+1) % messages.length;
showOne(Quotenum);
}
function showPrev() {
showOne(LastQuote);
}
var messages = [
"All looks yellow to a jaundice eye.",
"You never get to old to learn a new way of being stupid!",
"Never squat with your spurs on.",
"Always drink upstream from the herd.",
"Don't spit into the wind.",
"Never kick a cow chip on a hot day.",
"Everyone has 20/20 hindsight!",
"Good judgment comes from experience<br> ... and a lot of that comes from bad judgment.",
"Never miss a good chance to shut up.",
"Jumping to conclusions can be bad exercise.",
"If you want your dreams to come true, don't oversleep.",
"Nobody ever goes blind from a bright idea.",
"Failure is the path of least persistence.",
"Minds are like parachutes - they function only when open.",
"The Ten Commandments are NOT multiple choice.",
"Success come in cans -- Failure comes in can'ts.",
"2/3 of promotion is motion.",
"If you don't care where you are going, any road will get you there.",
"There's two theories to arguin' with a woman.<br> - Neither one works.",
"An apple a day keeps the doctor at bay.",
"When in the course of inhuman events.",
"All's well that ends swell.",
"Never look a gift horse in the spleen."
];
var numbers = [];
for ( var n = 0; n < messages.length; ++n ) { numbers[n] = n; }
numbers.sort( function() { return Math.random() - 0.5; } );
alert(numbers);

var Quotenum = 0;
var LastQuote = 0;
</script>

</head>
<body>
<button onclick="showPrev()">Previous Quote</button>
<button onclick="showNext()">New Quote of the Day</button>
<div id="whatever"></div>
</body>
</html>

Added a few more quotes to randomize display a bit more :)

Clownie
04-21-2012, 06:30 PM
Hey xelawho, thanks again for you help.

But it seems there's something not working in the way you shuffle/randomize the array... seems to work fine with very small array (the example you gave), but when I use it on a 24 elements array, you can see/smell that it almost always start with the first elements before going to the lasts...

And on very large arrays (+1000), it doesn't work at all... it shuffles and stays only in the first 20 something elements, maybe will jump once or twice on a far away element (like 720) but very quickly will stop to function and will then only send 'undefined' as a result...

You can look here: http://keep-quiet.com (I've implemented the prior version you gave me on post #18 without the 'previous' function) and you can click the 'Annamalai Swami' link on the right menu, where I've implemented your last version on post #26 (with the 'previous' function, which is there on 'back' link)...

I don't want to bother you again... so maybe if you have a quick idea about why it is doing this... or else... it's ok... thanks for your help!

xelawho
04-21-2012, 10:36 PM
yes, it seems that the sort approach is only good for small arrays. Try it out with the original method you were using, and see if it gets more random...



<!DOCTYPE html>
<html>
<head>
</head>
<body>

<script type = "text/javascript">

function shuffle(v) {
for (var j, x, i = n = v.length; i; j = parseInt(Math.random() * n), x = v[--i], v[i] = v[j], v[j] = x);
return v;
}

var arQAnna = new Array ();
arQAnna[0] = "zero";
arQAnna[1] = "one";
arQAnna[2] = "two";
arQAnna[3] = "three";
arQAnna[4] = "four";
arQAnna[5] = "five";
arQAnna[6] = "six";
arQAnna[7] = "seven";
arQAnna[8] = "eight";
arQAnna[9] = "nine";
arQAnna[10] = "ten";

var randArr=[];
for(var x=0;x<arQAnna.length;x++){
randArr.push(x)
}

randArr=shuffle(randArr);

var inTemp = -1;

function randomAnna(dir) {

inTemp=dir=="up"?inTemp+1:inTemp-1;

if (inTemp==arQAnna.length) {
inTemp = 0;
randArr=shuffle(randArr);
}

if (inTemp<0) {
inTemp++;
return};

var str=""
var quote=randArr[inTemp];
document.getElementById("qotmo").innerHTML = "random element is: "+arQAnna[quote];
intQuoteIndex = inTemp;
document.getElementById("qotidanna").innerHTML = "element is now at position: "+intQuoteIndex;
document.getElementById("orig").innerHTML = "original position: "+quote;

for(var x=0;x<randArr.length;x++){
str+=arQAnna[randArr[x]]+", ";
}
document.getElementById("shuforder").innerHTML = "array is now: "+str;
}

</script>

<a href="#" onclick="randomAnna('up');return false">test 1</a><br/><br/>
<a href="#" onclick="randomAnna('dn');return false">Previous</a><br/><br/>
<span id="qotmo"></span><br><br/>
<span id="qotidanna"></span><br><br/>
<span id="orig"></span><br><br/>
<span id="shuforder"></span>
</body>
</html>

Clownie
04-21-2012, 11:18 PM
Hey xelawho... again, thanks... yes, it seems it's working really better (for the small arrays... i.e the 'Annamalai Swami' right menu link), but it's still the exact problem with the +1000 elements array in the homepage... it gets stuck in elements between 0 to 20 something for a while, then keeps returning 'undefined'...

Edit: Oh... wait, wait, I switched the data between my scripts, and it apparently works with large array on the other one... so must be a bug in the other one... will check this out!

felgall
04-21-2012, 11:30 PM
[code]
numbers.sort( function() { return Math.random() - 0.5; } );

0.75 will give more random results than 0.5 - but even then there will be a very slight bias toward entries staying closer to where they started. 0.8 will give a similarly slight bias toward the entries moving away from where they started.

Clownie
04-22-2012, 12:16 AM
Hey there! Ok... xelawho... it's working great! http://keep-quiet.com So, really, thank you xelawho, and thank you to all here that helped (even if it was not directly, I learned a lot from all your code examples or approaches).

And by the way, the shuffle function that was shared in this thread a year ago, and that xelawho used in the last code, seems really good (as far as I can tell, on a +1000 elements array)...


function shuffle(v) {
for (var j, x, i = n = v.length; i; j = parseInt(Math.random() * n), x = v[--i], v[i] = v[j], v[j] = x);
return v;
}

You rocks guys! ;-)

felgall
04-22-2012, 12:42 AM
parseInt(Math.random() * n)

doesn't make much sense - the value should already be a base 10 number so no meed to convert it to base 10 (which is what parseInt does).

possibly you meant to get the integer portion of the number in which case you should be using:

Math.floor(Math.random() * n)

Clownie
04-22-2012, 04:38 PM
Just to say that, along with xelawho scripts, I actually ended using this method/script to shuffle the arrays.


function shuffle(v) {
var s = [];
while (v.length) s.push(v.splice(Math.random() * v.length, 1));
while (s.length) v.push(s.pop());
return v;
}

Philip M gave it at the top of this thread, and is apparently coming from Stephen "felgall" at http://www.codingforums.com/showpost.php?p=1195197&postcount=6

It really seems to be a very good unbiased shuffle method, and works smoothly with +1000 elements arrays... Thanks to all.