Why won't my code invoke this method of the object? - javascript

There is an event handler in the body tag.
<body onload="hangmanGame.populateQuestions();">
It is supposed to get a random position of the array...
const hangmanGame = {
obtainRandom(x) {
return Math.floor(Math.random() * Math.floor(x));
},
populateQuestions() {
let randNum = obtainRandom(5);
let numToPopulate = stemQuestions[randNum];
console.log(randNum);
console.log(numToPopulate);
},
stemQuestions : ['What do roots of a quadratic equation represent in a parabola?',
'What is a chemical process where a solid turns into a gas without going through a liquid stage',
'What is the name of the peculiar kind of inheritance pertinent to JavaScript?',
'What is the product of mass and velocity?',
'What is acceleration with respect to velocity?'],
stemAnswers : ['intercepts','sublimation','prototype','momentum','derivative']
}
But according to the console, both values are undefined...
Can you please give me some insight?

obtainRandom and stemQuestions are properties of hangmanGame, so in order to refer to them from inside populateQuestions you need to use this:
populateQuestions() {
let randNum = this.obtainRandom(5);
let numToPopulate = this.stemQuestions[randNum];
console.log(randNum);
console.log(numToPopulate);
}

Related

Need help on using random to get a random string from array

I already know how to pull random from an array but this won't work. Trying to make an HTML game.
I use Caret.
I'm pretty new to coding but know most of the basics.
function person() {
...
interests = ["food", "clothes", "tech"]; //interest definition because I keep getting "undefined"
var rand = Math.floor(Math.random() * 3); //random var
instrestscho = interests[rand]; //interest random string puller that's not working
...
}
}
I spy an extra:
}
I'm guessing this is the error because everything else should work.
Also, if the point of this function is to grab a random interest, you may want to return it, like so:
function person() {
interests = ["food", "clothes", "tech"]; //interests definition
var rand = Math.floor(Math.random() * interests.length); //random var
return interests[rand]; //return interest random string
}
console.log( person() );

Using jQuery and Math.random() to select nested objects properties

I'm creating a random quote machine that will present a random quote from various philosophers.
I have an object literal with nested objects containing philosophers and their quotes. Using jQuery functions and Math.random(), how can I select a random quote from my object literal structure? Is there a better way to organize the data?
I've started with a jQuery closure that will display a designated quote that I'd like to modify using Math.random().
Looking for explanations to solutions as I'm a beginner. Thanks in advance.
Example object literal:
var quotes =
{
awatts: {
name: "Alan Watts",
quote: "The only way to make sense out of change is to plunge into it, move with it, and join the dance."
},
etolle: {
name: "Eckhart Tolle",
quote: "Realize deeply that the present moment is all you ever have."
},
tmckenna: {
name: "Terrence Mckenna",
quote: "“The cost of sanity in this society, is a certain level of alienation” "
}
};
Example jQuery functions with single quote selected:
$(document).ready(function() {
$('.mybutton').click(function() {
$('#quote').html(quotes.awatts.quote);
});
});
The structure of the data seems fine. You could use an array, but an object isn't a problem.
You'd get the keys from the object, and then pick a random key
var quotes = {
awatts: {
name: "Alan Watts",
quote: "The only way to make sense out of change is to plunge into it, move with it, and join the dance."
},
etolle: {
name: "Eckhart Tolle",
quote: "Realize deeply that the present moment is all you ever have."
},
tmckenna: {
name: "Terrence Mckenna",
quote: "“The cost of sanity in this society, is a certain level of alienation” "
}
};
$('.mybutton').click(function() {
var keys = Object.keys(quotes);
var rand = keys[Math.floor(Math.random() * keys.length)];
$('#quote').html(quotes[rand].quote);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="mybutton">Quote</button>
<br><br>
<div id="quote"></div>
If you can make your quotes object an array, the following would do the trick. Change your array
var quotes = [
{
name: "Alan Watts",
quote: "The only way to make sense out of change is to plunge into it, move with it, and join the dance."
},
{
name: "Eckhart Tolle",
quote: "Realize deeply that the present moment is all you ever have."
},
{
name: "Terrence Mckenna",
quote: "“The cost of sanity in this society, is a certain level of alienation” "
}
];
Set the max and min (to set the upper and lower limits for the random number)
var max = quotes.length, min = 0;
Generate a random number
var rand = Math.random() * (max - min) + min;
On the click event use the random number to choose your random quote
$('#quote').html(quotes[rand]quote);
I have not tested the code. Hope this will get you going :-)

Determine the key of a song by its chords

How can I programmatically find the key of a song just by knowing the chord sequence of the song?
I asked some people how they would determine the key of a song and they all said they do it 'by ear' or by 'trial and error' and by telling if a chord resolves a song or not... For the average musician that is probably fine, but as a programmer that really isn't the answer that I was looking for.
So I started looking for music related libraries to see if anyone else has written an algorithm for that yet. But although I found a really big library called 'tonal' on GitHub: https://danigb.github.io/tonal/api/index.html I couldn't find a method that would accept an array of chords and return the key.
My language of choice will be JavaScript (NodeJs), but I'm not necessarily looking for a JavaScript answer. Pseudo code or an explanation that can be translated into code without too much trouble would be totally fine.
As some of you mentioned correctly, the key in a song can change. I'm not sure if a change in key could be detected reliably enough. So, for now let's just say, I'm looking for an algorithm that makes a good approximation on the key of a given chord sequence.
...
After looking into the circle of fifths, I think I found a pattern to find all chords that belong to each key. I wrote a function getChordsFromKey(key) for that. And by checking the chords of a chord sequence against every key, I can create an array containing probabilities of how likely it is that the key matches the given chord sequence: calculateKeyProbabilities(chordSequence). And then I added another function estimateKey(chordSequence), which takes the keys with the highest probability-score and then checks if the last chord of the chord sequence is one of them. If that is the case, it returns an array containing only that chord, otherwise it returns an array of all chords with the highest probability-score.
This does an OK job, but it still doesn't find the correct key for a lot of songs or returns multiple keys with equal probabililty. The main problem being chords like A5, Asus2, A+, A°, A7sus4, Am7b5, Aadd9, Adim, C/G etc. that are not in the circle of fifths. And the fact that for instance the key C contains the exact same chords as the key Am, and G the same as Em and so on...
Here is my code:
'use strict'
const normalizeMap = {
"Cb":"B", "Db":"C#", "Eb":"D#", "Fb":"E", "Gb":"F#", "Ab":"G#", "Bb":"A#", "E#":"F", "B#":"C",
"Cbm":"Bm","Dbm":"C#m","Eb":"D#m","Fbm":"Em","Gb":"F#m","Ab":"G#m","Bbm":"A#m","E#m":"Fm","B#m":"Cm"
}
const circleOfFifths = {
majors: ['C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#', 'G#','D#','A#','F'],
minors: ['Am','Em','Bm','F#m','C#m','G#m','D#m','A#m','Fm','Cm','Gm','Dm']
}
function estimateKey(chordSequence) {
let keyProbabilities = calculateKeyProbabilities(chordSequence)
let maxProbability = Math.max(...Object.keys(keyProbabilities).map(k=>keyProbabilities[k]))
let mostLikelyKeys = Object.keys(keyProbabilities).filter(k=>keyProbabilities[k]===maxProbability)
let lastChord = chordSequence[chordSequence.length-1]
if (mostLikelyKeys.includes(lastChord))
mostLikelyKeys = [lastChord]
return mostLikelyKeys
}
function calculateKeyProbabilities(chordSequence) {
const usedChords = [ ...new Set(chordSequence) ] // filter out duplicates
let keyProbabilities = []
const keyList = circleOfFifths.majors.concat(circleOfFifths.minors)
keyList.forEach(key=>{
const chords = getChordsFromKey(key)
let matchCount = 0
//usedChords.forEach(usedChord=>{
// if (chords.includes(usedChord))
// matchCount++
//})
chords.forEach(chord=>{
if (usedChords.includes(chord))
matchCount++
})
keyProbabilities[key] = matchCount / usedChords.length
})
return keyProbabilities
}
function getChordsFromKey(key) {
key = normalizeMap[key] || key
const keyPos = circleOfFifths.majors.includes(key) ? circleOfFifths.majors.indexOf(key) : circleOfFifths.minors.indexOf(key)
let chordPositions = [keyPos, keyPos-1, keyPos+1]
// since it's the CIRCLE of fifths we have to remap the positions if they are outside of the array
chordPositions = chordPositions.map(pos=>{
if (pos > 11)
return pos-12
else if (pos < 0)
return pos+12
else
return pos
})
let chords = []
chordPositions.forEach(pos=>{
chords.push(circleOfFifths.majors[pos])
chords.push(circleOfFifths.minors[pos])
})
return chords
}
// TEST
//console.log(getChordsFromKey('C'))
const chordSequence = ['Em','G','D','C','Em','G','D','Am','Em','G','D','C','Am','Bm','C','Am','Bm','C','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Am','Am','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em','Em','C','D','Em']
const key = estimateKey(chordSequence)
console.log('Example chord sequence:',JSON.stringify(chordSequence))
console.log('Estimated key:',JSON.stringify(key)) // Output: [ 'Em' ]
The chords in a song of a particular key are predominantly members of the key's scale. I imagine you could get a good approximation statistically (if there is enough data) by comparing the predominant accidentals in the chords listed to the key signatures of the keys.
See https://en.wikipedia.org/wiki/Circle_of_fifths
Of course, a song in any key can/will have accidentals not in the keys scale, so it would likely be a statistical approximation. But over several bars, if you add up the accidentals and filter out all but the ones that occur most often, you may be able to match to a key signature.
Addendum: as Jonas w correctly points out, you may be able to get the signature, but you won't likely be able to determine if it is a major or minor key.
Here's what I came up with. Still new with modern JS so apologies for messiness and bad use of map().
I looked around the internals of the tonal library, it has a function scales.detect(), but it was no good since it required every note present. Instead I used it as inspiration and flattened the progression into a simple note list and checked this in all transpositions as a subset of all the possible scales.
const _ = require('lodash');
const chord = require('tonal-chord');
const note = require('tonal-note');
const pcset = require('tonal-pcset');
const dictionary = require('tonal-dictionary');
const SCALES = require('tonal-scale/scales.json');
const dict = dictionary.dictionary(SCALES, function (str) { return str.split(' '); });
//dict is a dictionary of scales defined as intervals
//notes is a string of tonal notes eg 'c d eb'
//onlyMajorMinor if true restricts to the most common scales as the tonal dict has many rare ones
function keyDetect(dict, notes, onlyMajorMinor) {
//create an array of pairs of chromas (see tonal docs) and scale names
var chromaArray = dict.keys(false).map(function(e) { return [pcset.chroma(dict.get(e)), e]; });
//filter only Major/Minor if requested
if (onlyMajorMinor) { chromaArray = chromaArray.filter(function (e) { return e[1] === 'major' || e[1] === 'harmonic minor'; }); }
//sets is an array of pitch classes transposed into every possibility with equivalent intervals
var sets = pcset.modes(notes, false);
//this block, for each scale, checks if any of 'sets' is a subset of any scale
return chromaArray.reduce(function(acc, keyChroma) {
sets.map(function(set, i) {
if (pcset.isSubset(keyChroma[0], set)) {
//the midi bit is a bit of a hack, i couldnt find how to turn an int from 0-11 into the repective note name. so i used the midi number where 60 is middle c
//since the index corresponds to the transposition from 0-11 where c=0, it gives the tonic note of the key
acc.push(note.pc(note.fromMidi(60+i)) + ' ' + keyChroma[1]);
}
});
return acc;
}, []);
}
const p1 = [ chord.get('m','Bb'), chord.get('m', 'C'), chord.get('M', 'Eb') ];
const p2 = [ chord.get('M','F#'), chord.get('dim', 'B#'), chord.get('M', 'G#') ];
const p3 = [ chord.get('M','C'), chord.get('M','F') ];
const progressions = [ p1, p2, p3 ];
//turn the progression into a flat string of notes seperated by spaces
const notes = progressions.map(function(e) { return _.chain(e).flatten().uniq().value(); });
const possibleKeys = notes.map(function(e) { return keyDetect(dict, e, true); });
console.log(possibleKeys);
//[ [ 'Ab major' ], [ 'Db major' ], [ 'C major', 'F major' ] ]
Some drawbacks:
- doesn't give the enharmonic note you want necessarily. In p2, the more correct response is C# major, but this could be fixed by checking somehow with the original progression.
-‎ won't deal with 'decorations' to chords that are out of the key, which might occur in pop songs, eg. CMaj7 FMaj7 GMaj7 instead of C F G. Not sure how common this is, not too much I think.
Given an array of tones like this:
var tones = ["G","Fis","D"];
We can firstly generate a unique Set of tones:
tones = [...new Set(tones)];
Then we could check for the appearence of # and bs :
var sharps = ["C","G","D","A","E","H","Fis"][["Fis","Cis","Gis","Dis","Ais","Eis"].filter(tone=>tones.includes(tone)).length];
Then do the same with bs and get the result with:
var key = sharps === "C" ? bs:sharps;
However, you still dont know if its major or minor, and many componists do not care of the upper rules (and changed the key inbetween )...
One approach would be to find all the notes being played, and compare to the signature of different scales and see which is the best match.
Normally a scale signature is pretty unique. A natural minor scale will have the same notes as a major scale (that is true for all the modes), but generally when we say minor scale we mean the harmonic minor scale, which has a specific signature.
So comparing what notes are in the chords with your different scales should give you a good estimate. And you could refine by adding some weight to different notes (for example the ones that come up the most, or the first and last chords, the tonic of each chord, etc.)
This seems to handle most basic cases with some accuracy:
'use strict'
const allnotes = [
"C", "C#", "D", "Eb", "E", "F", "F#", "G", "Ab", "A", "Bb", "B"
]
// you define the scales you want to validate for, with name and intervals
const scales = [{
name: 'major',
int: [2, 4, 5, 7, 9, 11]
}, {
name: 'minor',
int: [2, 3, 5, 7, 8, 11]
}];
// you define which chord you accept. This is easily extensible,
// only limitation is you need to have a unique regexp, so
// there's not confusion.
const chordsDef = {
major: {
intervals: [4, 7],
reg: /^[A-G]$|[A-G](?=[#b])/
},
minor: {
intervals: [3, 7],
reg: /^[A-G][#b]?[m]/
},
dom7: {
intervals: [4, 7, 10],
reg: /^[A-G][#b]?[7]/
}
}
var notesArray = [];
// just a helper function to handle looping all notes array
function convertIndex(index) {
return index < 12 ? index : index - 12;
}
// here you find the type of chord from your
// chord string, based on each regexp signature
function getNotesFromChords(chordString) {
var curChord, noteIndex;
for (let chord in chordsDef) {
if (chordsDef[chord].reg.test(chordString)) {
var chordType = chordsDef[chord];
break;
}
}
noteIndex = allnotes.indexOf(chordString.match(/^[A-G][#b]?/)[0]);
addNotesFromChord(notesArray, noteIndex, chordType)
}
// then you add the notes from the chord to your array
// this is based on the interval signature of each chord.
// By adding definitions to chordsDef, you can handle as
// many chords as you want, as long as they have a unique regexp signature
function addNotesFromChord(arr, noteIndex, chordType) {
if (notesArray.indexOf(allnotes[convertIndex(noteIndex)]) == -1) {
notesArray.push(allnotes[convertIndex(noteIndex)])
}
chordType.intervals.forEach(function(int) {
if (notesArray.indexOf(allnotes[noteIndex + int]) == -1) {
notesArray.push(allnotes[convertIndex(noteIndex + int)])
}
});
}
// once your array is populated you check each scale
// and match the notes in your array to each,
// giving scores depending on the number of matches.
// This one doesn't penalize for notes in the array that are
// not in the scale, this could maybe improve a bit.
// Also there's no weight, no a note appearing only once
// will have the same weight as a note that is recurrent.
// This could easily be tweaked to get more accuracy.
function compareScalesAndNotes(notesArray) {
var bestGuess = [{
score: 0
}];
allnotes.forEach(function(note, i) {
scales.forEach(function(scale) {
var score = 0;
score += notesArray.indexOf(note) != -1 ? 1 : 0;
scale.int.forEach(function(noteInt) {
// console.log(allnotes[convertIndex(noteInt + i)], scale)
score += notesArray.indexOf(allnotes[convertIndex(noteInt + i)]) != -1 ? 1 : 0;
});
// you always keep the highest score (or scores)
if (bestGuess[0].score < score) {
bestGuess = [{
score: score,
key: note,
type: scale.name
}];
} else if (bestGuess[0].score == score) {
bestGuess.push({
score: score,
key: note,
type: scale.name
})
}
})
})
return bestGuess;
}
document.getElementById('showguess').addEventListener('click', function(e) {
notesArray = [];
var chords = document.getElementById('chodseq').value.replace(/ /g,'').replace(/["']/g,'').split(',');
chords.forEach(function(chord) {
getNotesFromChords(chord)
});
var guesses = compareScalesAndNotes(notesArray);
var alertText = "Probable key is:";
guesses.forEach(function(guess, i) {
alertText += (i > 0 ? " or " : " ") + guess.key + ' ' + guess.type;
});
alert(alertText)
})
<input type="text" id="chodseq" />
<button id="showguess">
Click to guess the key
</button>
For your example, it gives G major, that's because with a harmonic minor scale, there are no D major or Bm chords.
You can try easy ones: C, F, G or Eb, Fm, Gm
Or some with accidents: C, D7, G7 (this one will give you 2 guesses, because there's a real ambiguity, without giving more information, it could be both)
One with accidents but accurate: C, Dm, G, A
You might be able too keep an structure with keys for every "supported" scale, with as value an array with chords matching that scale.
Given a chord progression you can then start by making a shortlist of keys based on your structure.
With multiple matches you can try to make an educated guess. For example, add other "weight" to any scale that matches the root note.
You can use the spiral array, a 3D model for tonality created by Elaine Chew, which has a key detection algorithm.
Chuan, Ching-Hua, and Elaine Chew. "Polyphonic audio key finding using the spiral array CEG algorithm." Multimedia and Expo, 2005. ICME 2005. IEEE International Conference on. IEEE, 2005.
My recent tension model, which is available in a .jar file here, also outputs the key (in addition to the tension measures) based on the spiral array. It can either take a musicXML file or text file as input that just takes a list of pitch names for each 'time window' in your piece.
Herremans D., Chew E.. 2016. Tension ribbons: Quantifying and visualising tonal tension. Second International Conference on Technologies for Music Notation and Representation (TENOR). 2:8-18.
If you're not opposed to switching languages, music21 (my library, disclaimer) in Python would do this:
from music21 import stream, harmony
chordSymbols = ['Cm', 'Dsus2', 'E-/C', 'G7', 'Fm', 'Cm']
s = stream.Stream()
for cs in chordSymbols:
s.append(harmony.ChordSymbol(cs))
s.analyze('key')
Returns: <music21.key.Key of c minor>
The system will know the difference between, say C# major and Db major. It has a full vocabulary of chord names so things like "Dsus2" won't confuse it. The only thing that might bite a newcomer is that flats are written with minus signs so "E-/C" instead of "Eb/C"
There is an online free tool (MazMazika Songs Chord Analyzer), which analyzes and detects the chords of any song very fast. You can process the song through file upload (MP3/WAV) or by pasting YouTube / SoundCloud links. After processing the file, you can play the song while seeing all the chords playing along in-real time, as well as a table containing all the chords, each chord is assigned to a time-position & a number ID, which you can click to go directly to the corresponding chord and it`s time-position.
https://www.mazmazika.com/chordanalyzer

Unexpected Type Error - Javascript, multidimensional arrays

I'm learning to code Javascript. I'm trying to create a random quote generator. The idea is that I have a method that creates a multidimensional array, with each element array having a quote and the author's name. This method returns the multidimensional array.
I assign this returned multidimensional array to a variable and pick a random element array. It gives me an "Unexpected Type Error" in the console.
<script>
var colors = ['#16a085', '#27ae60', '#2c3e50', '#f39c12', '#e74c3c', '#9b59b6',
'#FB6964', '#342224', '#472E32', '#BDBB99', '#77B1A9', '#73A857'];
console.log("Hi!");
function getQuote(){
var quotesAndAuthors =
[
['But suicides have a special language. Like carpenters, they want to know "which tools", they never ask "why build"', "Anne Sexton"],
['Here is the world. Beautiful and terrible things will happen. Dont be afraid', 'Frederick Buechner'],
['All grown-ups were once children, but only a few of them remember it', 'Alexander de Saint-Exupery'],
['It was love at first sight, at last sight, at ever ever sight', 'Vladimir Nabokov'],
['A paradise the color of hell flames, but a paradise nonetheless', 'Vladimir Nabokov'],
['There is nothing like the deep breaths after laughing that hard. Nothing in the world like a sore stomach for the right reasons','Stephen Chbosky'],
['And then suddenly, something is over','Louise Gluck'],
['Adventure is out there!', 'Up (Pixar)'],
['The strong do what they can, and the weak suffer what the must', 'Thucydides'],
['But who prays for Satan? Who, in eighteen centuries, has had the common humanity to pray for the one sinner that needed it most?', 'Mark Twain'],
['I stopped explaining myself when I realized people only understand from their level of perception', 'Unknown'],
['Unexpressed emotions will never die. They are buried alive and will come forth in uglier ways', 'Sigmund Freud'],
['Genius might be the ability to say a profound thing in a simple way', 'Charles Bukowski']
];
return quotesAndAuthors;
}
function generate(){
var pickColor = Math.floor(Math.random * colors.length);
$('html body').animate({
backgroundColor: colors[pickColor]
}, 1000);
$('#text #author').animate({
color: colors[pickColor]
}, 500);
$('.buttons').animate({
backgroundColor: colors[pickColor]
},500);
var quotes = getQuote();
var n = Math.floor(Math.random * quotes.length);
var quoteText = quotes[n][0];
var quoteAuthor = quotes[n][1];
$('#text').text(quoteText);
$('#author').text(quoteAuthor);
}
$(document).ready(function(){
generate();
alert("Testing");
$('#quoteButton').on('click', generate());
});
</script>
Also, suggestions on how to store quotes more effectively would be appreciated.
random is a function and not a property. You should use paranthesis like
var n = Math.floor(Math.random() * quotes.length);
Also while adding event listeners, you should not use paranthesis, as this will call the method before even click event. Just give the function name.
$('#quoteButton').on('click', generate);
Also it's better to use arrary of objects in your case as below:
var quotesAndAuthors = [
{
"quote" : "But suicides have a special language",
"athour" : "Anne Sexton"
},
{
"quote" : "All grown-ups were once children",
"athour" : "Alexander de Saint-Exupery"
}
];
And you can access the quote as below using either of the method:
console.log(quotesAndAuthors[0]["quote"]);
console.log(quotesAndAuthors[0].quote);
.random is not a property of the Math object.
Math.random() is a method.
You wanted to call Math.random() because that's a function (note the parenthesis). That was generating your error.

random quote without back to back

I'm trying to pull a random quote from an array. I need to display an initial quote and then get a new one, no same two quotes back to back. Here's what I got.
$(document).ready(function() {
var quoter = [{
quote: "I drink to make other people more interesting.",
author: "Ernest Hemingway"
}, {
quote: "Alcohol may be man's worst enemy, but the bible says love your enemy.",
author: "Frank Sinatra"
}, {
quote: "Reality is an illusion created by a lack of alcohol.",
author: "N.F. Simpson"
},{
quote: "Time is never wasted when you’re wasted all the time.",
author: "Catherine Zandonella"
},{
quote: "I feel bad for people who don’t drink. When they wake up in the morning, that’s as good as they’re going to feel all day.",
author: "Frank Sinatra"
}];
var randomQuote = Math.floor(Math.random() * quoter.length);
//$(function () {
//Set Original Quote
$('#quoteText').text(quoter[randomQuote].quote);
$('#authorText').text(quoter[randomQuote].author);
//});
$('#btnNew').click(function(evt) {
//prevent browser's default action
evt.preventDefault();
//getting a new random number to attach to a quote and setting a limit
var sourceLength = quoter.length;
var randomNumber = Math.floor(Math.random() * sourceLength);
//set a new quote
//while ( randomNumber <= sourceLength ) {
while (randomNumber === randomNumber){
var newQuoteText = quoter[randomNumber].quote;
var newQuoteGenius = quoter[randomNumber].author;
var timeAnimation = 500;
var quoteContainer = $('#quoteContainer');
//fade out animation with callback
quoteContainer.fadeOut(timeAnimation, function() {
//set text values
$('#quoteText').text(newQuoteText);
$('#authorText').text(newQuoteGenius);
//console.log(quoteText,authorText);
//fadein animation.
quoteContainer.fadeIn(timeAnimation);
});
break;
}; //end while loop
}); //end btnNew function
}); //end document ready
I need to do this by using a while loop. I can't figure out how to store the random quote (array value) and then compare it to the new random one to get a different random on if it's the same.
The HTML is here:
<div id="quoteContainer">
<p><span id="quoteText"></span><Br/></p>
—<span id="authorText"> </span>
</div>
You can have a simple variable store the previous value, then check to see if the random number is the same as the last time.
$(document).ready(function(){
//....your current above code
var lastQuote = randomQuote;
$(button).click(function(){
var thisQuote = Math.floor(Math.random() * sourceLength);
//This will only be entered if the two are equal
//The while loop ensures that if you get a new random number
//it won't be the same
while(thisQuote == lastQuote){
thisQuote = Math.floor(Math.random() * sourceLength);
}
//If you make it here a unique number has been found
lastQuote = thisQuote;
});
});
Your approach might result in an infinite loop. Won't happen, because the random-number generator is not perfect but it can be done easier:
Either shuffel the array and go down linearly (or construct a fancy generator if you want) or just delete every quote that has been shown already.

Categories

Resources