Random link javascript to ignore current page - javascript

When I click the 'Random' link on my navbar (bootstrap) it refers to Javascript code (below) taking me to a random page on my mock website.
However I would like to add a feature, so if I'm on, say Link[2]=fed-rates.html, when I press the 'Random' link on my navbar it always takes me away from the page I'm currently on (that is, it ignores Link[2]).
I'm wondering whether this is possible, would be great to get some ideas.
Javascript code:
function randomlinks(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="articles/how-to-trade-oil.html"
links[1]="articles/usd-yen-gbp.html"
links[2]="articles/fed-rates.html"
window.location=links[myrandom]
}
// above is for all web pages
function randomlinksarticle(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="how-to-trade-oil.html"
links[1]="usd-yen-gbp.html"
links[2]="fed-rates.html"
window.location=links[myrandom]
}
// above is so navbar link still works on the linked pages, with the way I have the folder directory setup
New code that comes up with "/undefined" page:
function randomlinksarticle(){
var myrandom=Math.round(Math.random()*2)
var links=new Array()
links[0]="how-to-trade-oil.html"
links[1]="usd-yen-gbp.html"
links[2]="fed-rates.html"
links.forEach(function(link, index) {
if (location.href.indexOf(link) !== -1) {
links.splice(index, 1);
}});
window.location=links[myrandom]

You can do the following:
links.forEach(function(link, index) {
if (location.href.indexOf(link) !== -1) {
links.splice(index, 1);
}
});
This looks through all the links and checks if they exist in the current URL. If they do, it removes them from the list using the splice function.
Add this code after setting link[2], since that's when it should be removing the current page.
Edit: I also noticed that your random function isn't evenly distributed. Not that it matters that much, but it could cause problems for you. The reason for this is that there are many more numbers between 0 and 2 that round to 1 than to 0 or two. In order to get a zero from your random number scale, Math.random() has to be less than 0.5. Likewise, it has to be greater than or equal to 1.5 to get a 2. you have a 0.5/2 or 1/4 probability for 0 and 2. This leaves a 1/2 probability for getting one, which makes sense since all numbers between 0.5 and 1.5 would give you a 1.
tl;dr: Use math.floor(Math.random() * (maximum + 1)) rather than Math.round(Math.random() * maximum) for generating random numbers.
Also, if you want a less repetitive way to do this, you could substitute both functions for something like this:
function randomLink() {
var links = Array.prototype.slice.call(arguments, 0); //Turns the function's arguments into an array
links.forEach(function(link, index) { //Loops through all the links
if (location.href.indexOf(link) !== -1) { //If the link text is contained in the url
links.splice(index, 1); //Remove the link from the links array
}
});
var rand = Math.floor(Math.random() * links.length); //Choose a number between 0 and links.length - 1
window.location = links[rand]; //Visit the link
}
You could call this like randomLink("first_page.html", "second_page.html") with an arbitrary number of pages.

Related

how to change list numbers to appear as images but still be treated as numbers

so I have 2 numbers that gets randomly generated from 1 to 13 but if a number is above 10 it gets treated as 10 similar to the blackjack game
function getRandomNumber2() {
let random = Math.floor(Math.random() * 12 + 1);
if (random > 10) {
return 10;
} else {
return random;
}
}
then i attached these numbers to variables then I put them in a list and I summed them
secondCard = getRandomNumber2()
cardsList = [firstCard, secondCard];
sumGAME = firstCard + secondCard;
now I want these numbers to show in the website as images but I can still sum them and all, let's say I got number 2 then the image attached to number 2 gets displayed and if i ask for new set of numbers then the images gets deleted and gets replaced with the new pic
what I tried to do
I tried to identify each one of the 13 images as an individual variable and put if statement that looks like this
if(cardsList[0]===1)
{cards.appendChild(card1)}
and kept going for all the cards
the issue
if I ask for new set of cards it doesn't delete the old images but adds 2 more to it

Is this JS Unique ID Generator Unreliable? (Getting collisions)

I am using the following JS function to generate unique IDs, which I got from another StackOverflow thread:
function generateUniqueID() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
I see that it combines the current Date/Time with an additional Randomizer.
Nonetheless, I verified that I'm getting collisions on every 4th or 5th operation of quickly adding items with IDs.
The function is called inside a JS loop to generate IDs from the list of current elements.
jQuery.each(mainEvents, function(index, item) {
// ...
// Generate gaps
gapEvents.push({"gapEventID" : "event-GAP" + generateUniqueID(),
"other" : other });
}
Is this function unreliable? Could it allow collisions in quick JS loop iterations?
I've pretty much ruled out "outside causes" (i.e. that this function isn't the culprit but something else could be), but if that's the case, I can't understand why Math.random() wouldn't keep me safe.
Very much so. You can use new Date().getTime() to get a unique id under the assumption that it takes longer than 1ms for each iteration. As you can tell from your data, that is false. Combined with an RNG that uses Math.floor, it's very possible to get repeated values. You will get repeat times whenever the interval is < 1ms. If you want unique IDs based around the concept of an RNG, I'd say just using Math.random() to the 10^15 is a better choice. 10^15 is the max size integer digit length that will never go past Number.MAX_SAFE_INTEGER.
Math.floor(Math.random() * Math.pow(10, 15))
Is this function unreliable?
In my opinion it really is.
Infact new Date().getTime() is an integer number that increases by 1 each millisecond, while Math.random() * 100 is a pseudo random number that gives a number in a range from 0 to 99.
So their sum might really repeat often if the function is called many times rapidly.
Think if the function is called two times per millisecond, it becomes very likely to have the same number twice. It has 1/100 of probability to happen (and these are pretty much the results I'm getting considering that I'm generating a list of 10.000 ids in about 1 second using that function and getting ~100 duplicates, which is pretty consistent as order of magnitude)
A random value is never a unique value. Even with a timestamp you can't guarantee that the outcome is 100% unique. However, you could minimize this by generating a larger (random) value.
Using a timestamp however, you cover yourself when there are multiple pushes at the same time. Using an extra random will create an almost unique value which, in most use cases is unique.
I'd suggest though to make that random value longer. Or create a GUID instead.
Create GUID / UUID in JavaScript?
Based on the responses the following compares the suggested methods.
But I think I'm going in the wrong direction for my needs. I will be using the ID/Sequence on the server-side to ensure uniqueness.
function run() {
var nums1 = new Set(), nums2 = new Set(), nums3 = new Set();
for (var i = 0; i < 10000; i++) {
nums1.add(originalMethod());
}
for (var i = 0; i < 10000; i++) {
nums2.add(concatMethod());
}
for (var i = 0; i < 10000; i++) {
nums3.add(random10To18thMethod());
}
console.clear();
console.log('Original Method set: ' + nums1.size);
console.log('Concat Method set: ' + nums2.size);
console.log('Math.Random 10^18 set: ' + nums3.size);
function originalMethod() {
return Math.round(new Date().getTime() + (Math.random() * 100));
}
function concatMethod() {
return Math.round(new Date().getTime() + '' + (Math.random() * 100));
}
function random10To18thMethod() {
return Math.random() * Math.pow(10, 18);
}
}
<button onclick="run()">Run Algorithms</button>

How to include more than one count up counter on a page

I found a nice simple bit of code to show a count up and I can easily vary the steps each count up makes. So this one counts up in 10's so 10, 20, 30, 40, 50, etc. appears on the page.
Code text is as follows
<script type="text/javascript">
var counter = 0
var timer; { counter = counter + 10;//increment the counter by 10
//display the new value in the div
document.getElementById("timer_container").innerHTML = counter;
}
</script>
</head>
<body onload='timer=setInterval("countUP()", 1000 );'>
<div id="timer_container"<0>/div>
</body>
</html>
What beats me however is how to include the counter multiple times on a single page with each counter using a different counting amount. I'd like to be able to include a lot of counters in a table on a page with each one going up in different amounts 1, 2, 3, 4 etc.
What this is for is to help my teacher wife with times tables on a big whiteboard so there would be 12 different colored areas on display featuring each times table from 1 to 12
Each colored box displayed will include:
image - mysite.com/3timestableicon.png
text - "3x Table"
counter code - going up in increments of 3 and stopping after 20 steps
text- "See - Each step is in 3's!"
I can probably figure out the table and all the different cells to make all this display correctly but I'm stuck getting more than one counter to appear on a single page at the moment so would appreciate any help on this bit.
The problem you have is that var counter = 0 is a global variable. So if you copy n paste the script multiple times, you're sharing the same variable.
I'm not sure how much programming experience you have, but the best way to do this would be to have a counting function. Your code snippet looks like you incorrectly pasted it, but you need to have a function, say count that increments a counter and wraps it when it gets to 12 (or however high you want to go) before looping around. Remove the if statement if you don't want it to loop.
var k = 0;
function count() {
if (k == 12) k = 0;
else k = k + 1;
// update your divs now with the new value of k
}
Then you can execute that with the interval function to count every x number of millis.
<body onload='timer=setInterval("count()", 1000 );'>
Then have an update function which updates the div's with the new values. And this function would apply a multiplier to the current counter (k) value.
function updateDisplay(id, multiplier) {
document.getElementById(id).innerHTML = k * multiplier;
}
Then you can wrap all that together for the times table of 1 to 12 by using this code in the count function to update all the div containers.
for (var n = 1; n <= 12; n++) {
updateDisplay("timer_container_" + n, n);
}
In your HTML you'd just add in 12 divs, each one with the id, "timer_container_1" etc.
I'll leave it as an exercise to the reader to put these functions together and the required divs into a HTML file.

How to select a random span from many spans javascript

I have a bunch of spans, they are set to display in-line block with a width and height of 60px, i want javascript to pick a random span from all of them and apply a color to it. I don't really even know where to begin with this. Any help would be appreciated.
For starters,
var elts = document.getElementsByTagName('span');
if using jQuery:
elts = $('span')
so now elts contains all the spans in the document.
The tricky part is selecting a random element within. We have to use Math.floor(Math.random() * elts.length) to select a random index. This is an earful, so the explanation:
Math.random() returns a random from [0,1).
elts.length is the length of the array. We multiply this by Math.random() to get a random array index from 0 to elts.length exclusive.
Math.floor() rounds down, so that we don't get an out of bounds exception.
Put it all together:
var myRandomSpan = elts[Math.floor(Math.random() * elts.length)]
and there you have it. You can do what you please with myRandomSpan.
You say you don't know where to begin. Well, with a little thought it becomes apparent:
1) Work out how to generate a random number in JS (easy Googling)
2) Work out how to pick out a random element form an array using point 1
3) Realise that a nodeset, e.g. as the result of getElementsByTagName or querySelectorAll is array-like (but not actually an array), and so we can pick out a particular element of it via square-bracket syntax, as with arrays. We can therefore apply point 2 to this nodeset.
So:
var
spans = document.querySelectorAll('span'),
span = spans[Math.floor(Math.random() * spans.length];
I have no idea if this will work - random code I pulled from various searches but in theory you could put all your spans into a array, count the length, generate random number bsaed on that length and access it via indecies:
var numSpans $("#container span").size();
var optionTexts = [];
// populat our span array
$("#container span").each(function() { optionTexts.push($(this).text()) });
var random = NumMath.floor(Math.random() * optionText.length);
var randomSpan = optionText[random];
You can give an integer id to your spans
<span id=1></span>
<span id=2></span>
...
<span id=100></span>
So, you just have to make a random number in between your ids. To generate a random integer between to numbers you can use this function:
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var randomID = getRandomInt(1, 100);
Then, with your random integer you can select the span like this:
document.getElementById(randomID)
If you are using jQuery you can change the background-color like this:
$("#" + randomID).css("background-color", {new_color})

Elegant way to bias random boolean

I'd like to create a random boolean in JavaScript, but I want to take the previous value into account. If the previous value was true, I want it to be more likely for the next value to be true. At the moment I've got this (this is in the context of a closure - goUp and lastGoUp are locals to the containing scope):
function setGoUp() {
goUp = getRandomBoolean();
if(lastGoUp) {
goUp = getRandomBoolean() || goUp;
}
else {
goUp = getRandomBoolean() && goUp;
}
lastGoUp = goUp;
}
So, the algorithm goes:
Get a random boolean
If the random boolean from the previous call was True:
a) get another random boolean, and or these two together
b) else get another random boolean and and these together.
I'm sure this algorithm could be simplified. I wondered about doing:
if(lastGoUp && goUp) {
goUp = goUp * (getRandomBoolean() || goUp);
}
but that seems really dirty.
There's also a problem with this algorithm which means that I can only double the chance of getting the same boolean again - I can't tweak it easily. Any ideas?
You should define the distribution you want, but maybe you are looking for the following?
if (lastGoUp) {
goUp = Math.random() < 0.8;
} else {
goUp = Math.random() < 0.2;
}
Instead of getting a random boolean, get a random number, say between 0 and 99. Keep a threshold value instead of the last number, and adjust the threshold according to the result:
var threshold = 50;
function setGoUp() {
goUp = getRandomNumber() < threshold;
threshold += goUp ? -10 : 10;
}
This would keep a running tab, so if you get consecutive results that are the same, the probability would keep falling for that result.
If you only want to consider the last result, you would instead set the threshold to a specific value:
threshold = goUp ? 40 : 60;
If you only want the probability of the next event to depend on the current value, and not the history of values up til now, what you want is called a Markov process. Often these are implemented with a 2D table of probabilities that you look up (prob of each next outcome given current one), but for a simple bool-valued event, an if statement is sufficient (see meriton's answer; note that it corresponds to a table of probabilities [0.8 0.2; 0.2 0.8]).
If you want something that gets more likely, say, the more successes you get in a row, then you need to devise a sequence of probabilities for success that perhaps approaches, but does not exceed, 1. There are any number of formulas which can do this, depending on how strong you want the bias to become and how quickly you want it to get there.
I would just make the probability of getting value true be an explicit float variable p. Then I could tweak it easily, by increasing p in some way if I got true last time or by doing nothing with it if I got 'false'.
Can replace Math.random for a better randomizer.
var setGoUp = (function(){
var last;
return function(){
// if last 66% chance for true else 50% chance of true.
return !!(last ? Math.random()*3 : Math.random()*2);
}
}());
!! converts anything to a boolean, 0 = false.

Categories