angular - Gör så att JavaScript Random Quote Generator bara genererar ett citat per dag
Jag har skapat en slumpmässig citatgenerator för min Angular-app. Komponentkoden ser ut så här:
qotd = this.quotes[Math.floor(Math.random() * this.quotes.length)];
Det drar från data som ser ut så här:
quotes = [
{
quote: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus euismod magna magna, euismod tincidunt libero dignis.",
author: 'Sorato Violasa'
},
{
quote: "Nullam dignissim accumsan magna vitae rhoncus. Phasellus euismod magna magna, euismod tincidunt libero dignis.",
author: 'Vito Dignaora'
},
{
quote: "In tincidunt imperdiet augue, quis sollicitudin mi tincidunt ut.",
author: 'Hivalo Amettioa'
},
{
quote: "hasellus accumsan erat vitae enim blandit, quis euismod ipsum sollicitudin.",
author: 'Grasha Plojiva'
},
];
Och sedan gör jag detta enligt min åsikt:
<div class="quotes">
<p class="quote">
{{qotd.quote}} <br><br>
~ {{qotd.author}}
</p>
</div>
Saken är den att just nu kommer detta att generera ett nytt citat varje gång komponenten laddas om, vilket kan ske flera gånger under en session. Vad jag inser nu skulle vara bättre är att göra detta till en daglig citatgenerator. Så det skulle bara generera ett nytt citat om datumet ändras. Vad är det enklaste sättet att implementera något sådant? Det är tillräckligt enkelt att generera datum och veckodag, så här:
date = new Date();
dayNumber = this.date.getDay();
Men hur skulle jag beräkna när veckodagen förändras för att starta en ny instans?
Svar #1
Tänk på ett upplägg där servern förbereder 3 citat: ett för igår, idag och imorgon. Varje ny dag tas gårdagens bort och en ny morgondag läggs till. På så sätt kan citatet på klienten ändras precis efter midnatt enligt klientens lokala tid och alla ser samma citat på deras samma lokala dag.
Ingenstans på jorden som är mer än 14 timmar skillnad från UTC, så om servern baserar nycklarna på UTC kommer varje klient att ha ett lämpligt antal citat och hela citatdatabasen skickas inte till varje klient varje gång den ändras.
var quotes = {
'20171012':{quote:'one',author:'fred'},
'20171013':{quote:'two',author:'mary'},
'20171014':{quote:'three',author:'sue'}
};
function showQuote(quotes) {
var d = new Date();
var key = '' + d.getFullYear() +
('0'+(d.getMonth()+1)).slice(-2) +
('0'+d.getDate()).slice(-2);
return quotes[key]
}
// On 2017-10-13 shows quote: two, author: mary
console.log(showQuote(quotes));Svar #2
Nej... Vänta... Om du behöver sätta specifika citat för varje dag, är det ett annat scenario än att få ett slumpmässigt citat från en citatlåda, men med samma citat varje 24 timmar, en dag. Om du har en array kan du troligen använda rand-funktionen och en räkning för att få det totala antalet värden i arrayen. Detta skulle returnera ett värde varje gång det laddas. Så det finns en annan funktion som kallas srand. Om du använder srand kommer du att sätta ett frö... och det fröet kommer att starta srand.
okej /
Så, fröet sätter srand-resultatet.. och srand gör slumpmässigheten. Du kan också prova shuffle-funktionen. Den använder också ett frö.
Nu behöver du hitta ett värde att använda som frö, och du behöver att det numret ändras inom ett 24-timmarsintervall.
För att använda ett intervall behövs ett referensvärde. Servertiden och användaragentens tid kan användas.
OM du använder fröet '42', får du samma resultat som returneras av srand.
Kolla in det: anta att du har en lista med 42 citat. Först skapa arrayen, sätt seed-variabeln, hämta värdet.
$numbers=range(1,42); $seed=floor(time()/86400); Värdet på seed sätts av serverns unix-tidsstämpel, dess tidszon är oberoende (=UTC). Eftersom det behövs en dagsinterval, beräkna genom att använda värdet 86400, totalt antal sekunder på en dag. Slumpa array shuffle($numbers); och skriv ut det första resultatet. Låt oss använda 200 citatlistan:
$quoteslist= range(1,200);
$seed = floor(time()/86400);
echo $seed;
$resultado = $quoteslist;
$seed = floor(time()/86400);
shuffle($resultado);
echo $resultado[$i];
Värdet som returneras av time(), tidsstämpeln, ändrades till 18846, det är fröet för idag.
Sedan blandar den listan med det värdet som frö.
Få det första resultatet.
// you need find the array count. Lets create an array of a 200 quotes .
$quotes = range(1,200);
$seed = floor(time()/86400);
echo 'the seed is:'. $seed.' and that changes on next day .';
echo '<hr>';
// makes another range to use the same index
$quotes = range(1,200);
$resultado = $quotes;
// first value of the array, no randomizing (its 1)
echo 'the first result of the range array : ';
echo $resultado[0];
echo '<hr>';
// lets echo the result of the shuffle, not using the srand and the seed, it prints each time one value .
$quotes = range(1,200);
$resultado = $quotes;
shuffle($resultado);
echo 'first result of thhe array, shuffled.. but not using the seed: ';
echo $resultado[0];
echo '<br> this changes each refresh';
echo " <hr> ";
// this prints a random number for each day, basing on using the seed
$quotes = range(1,200);
$resultado = $quotes;
echo 'today: ';
$seed = floor(time()/86400);
srand($seed);
shuffle($resultado);
echo $resultado[0];
echo " * this changes everyday, same result for all reloads <hr> ";
echo '<br>';
// this is the seed of today. using
$quotes = range(1,200);
$resultado = $quotes;
echo 'the day of seed 18846: first day - result never changes, because used specific seed : ';
srand(18846);
shuffle($resultado);
echo $resultado[0];
echo " <hr> ";
echo 'the result for 18847 seed , next day - never changes : ';
$quotes = range(1,200);
$resultado = $quotes;
// this is 2 days after
srand(18847);
shuffle($resultado);
echo $resultado[0];
