I'm working on a Random Quote Generator Project, and as part of the project, the second instruction is to create a getRandomQuote Function which
- should take in one parameter that will later get passed into this function when it is invoked will be the array of quotes.
- The body of the function should select and return a random quote object from the quotesarray.
I'm kinda confused with my code, I want a review on my code as to whether its fits the instruction. Below is my code, thanks!!
// An array of Objects with the quote and source as properties
var quotes = [
{
quote: "In the end, it’s not the years in your life that count. It’s the life in your years",
source: "Abraham Lincoln",
},
{
quote: "Don’t gain the world and lose your soul, wisdom is better than silver or gold",
source: "Bob Marley",
},
{
quote: "Lighten up, just enjoy life, smile more, laugh more, and don’t get so worked up about things",
source: "Kenneth Branagh",
},
{
quote: "Don’t cry because it’s over, smile because it happened",
source: "Ludwig Jacobowski",
},
{
quote: "Do stuff. Be clenched, curious. Not waiting for inspiration’s shove or society’s kiss on your forehead. Pay attention. It’s all about paying attention. Attention is vitality. It connects you with others. It makes you eager. Stay eager",
source: "Susan Sontag",
}
];
// getRandomQuote function selects and returns a random quote object
function getRandomQuote(array) {
for (var i = 0; i < quotes.length; i++) {
var quoteIndex = Math.floor(Math.random() * quotes.length);
var randomQuote = quoteIndex;
}
return randomQuote;
}
2 Answers 2
Random item from array
You don't need the for loop to select a random item from an array.
Just get an index using Math.floor(Math.random() * array.length)
function getRandomQuote(array) {
return array[Math.floor(Math.random() * array.length)];
}
Or as an arrow function, and you don't need the get
part of the function name that is implied.
const randomQuote = array => array[Math.floor(Math.random() * array.length)];
You can also use bitwise or zero | 0
in place of the Math.floor
function
const randomQuote = array => array[Math.random() * array.length | 0];
Random pick from array
If you wish to ensure each quote is randomly selected and not repeating until all have been randomly selected you can create a copy of the array, and pick items from that using Array.splice
until empty, then copy the source array again.
For example the function encapsulates array
and source
You must first call the function with an array, then any other calls will return a random item that does not repeat until all items have been picked.
const randomQuote = (() => {
const picked = []; // to hold picked items
var source; // array of items to pick from
return srcArray => {
if (srcArray) {
source = srcArray;
picked.length = 0;
} else {
if (!picked.length) { picked.push(...source) }
return picked.splice(Math.random() * picked.length | 0, 1)[0];
}
}
})();
randomQuote(["a","b","c","d","e","f"]); // set up the source array
console.log(randomQuote()); // display random quote in console.
At any time you can reset the source array by calling the function with an array.
Random and the array, common functions
Here is a set of common functions that use random to access arrays. Rather than have functions rely on each other, each function is written to be entirely stand alone. If you use many of them it will pay to encapsulate them all in an object.
const randItem = arr => arr[Math.random() * arr.length | 0];
const randPick = arr => arr.splice(Math.random() * arr.length | 0, 1)[0];
const randPut = (arr, item) => arr.splice(Math.random() * (arr.length + 1) | 0, 0, item);
const randShuffle = arr => {
var len = arr.length
while (len) {
arr.push(arr.splice(Math.random() * (len--) | 0, 1)[0]);
}
return arr;
}
const randPlay = (arr, repeat) {
var item;
repeat = repeat > arr.length ? arr.length : repeat
arr.push(item = arr.splice(Math.random() * repeat | 0, 1)[0]);
return item;
}
What they do.
randItem(array)
return a random item but does not remove itrandPick(array)
returns a random item removing it from the arrayrandPut(array, item)
randomly inserts the item into the arrayrandShuffle(array)
Shuffles the array in place (does not make a copy)randPlay(array, number)
A variation on the no repeat, selects random items from the bottomnumber
items. Good for play lists when you dont want to repeat the same track. Use withrandShuffle
on the array before you callrandPlay
. The same item will not play again until anotherarray.length - number
items have played.
var randomQuote = quoteIndex;
I think you shouldn't put var
there. Although var
declares the variable in the function's spoce, this seems like if randomQuote
were available inside the loop only. You may declare it outside the loop, and use let
:
function getRandomQuote(array) {
let randomQuote;
for (let i = 0; i < quotes.length; i++) {
randomQuote = Math.floor(Math.random() * quotes.length);
}
return randomQuote;
}
The function name is misleading. It does not get a quote, it just returns a random number which can be used to index the array quotes
to get a quote.
The function's parameter array
is unused. Did you wanted to pass quote
? If so, you should replace quotes.length
to array.length
.
The loop is totally useless. i
is not used anywhere, you just generate a random number in each iteration. Javascript arrays are indexable directly, so you need only one randomly generated index to return a random member of that array. See Blindman's answer.