【问题标题】:Make JavaScript Random Quote Generator Only Generate One Quote Per Day使 JavaScript 随机报价生成器每天只生成一个报价
【发布时间】:2017-10-12 22:28:18
【问题描述】:

我为我的 Angular 应用程序创建了一个随机报价生成器。组件代码如下所示:

qotd = this.quotes[Math.floor(Math.random() * this.quotes.length)];

这是从如下所示的数据中提取的:

  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'
    },
  ];

然后在我看来,我会这样做:

<div class="quotes">
    <p class="quote">
        {{qotd.quote}} <br><br>
        ~ {{qotd.author}}
    </p>
</div>

问题是,现在每次重新加载组件时都会生成一个新报价,这可能在一个会话中多次。我现在意识到更好的是让它成为每日报价生成器。因此,如果日期更改,它只会生成新的报价。实现这样的事情的最简单方法是什么?生成日期和星期几很容易,如下所示:

  date = new Date();
  dayNumber = this.date.getDay();

但是我将如何计算一周中的某一天何时更改以启动新实例?

【问题讨论】:

  • 你为什么要在客户端这样做?只需在服务器上执行,每天一次。
  • 公平点。那会奏效。但我仍然很好奇如何在客户端做到这一点。例如,当您访问可以读取的 API 时(用于获取引号),仅此而已。
  • 也许通过使用 PRNG 并获取今天的时间戳 Math.floor(Date.now() / 864e5) 种子。因此我可以生成一个可重复的“随机”数字序列,比如随机排列这个数组,或者获取一个索引,......或者更简单的东西,比如index = (Date.now() / 864e5 ^ 0xa702fa) % array.length
  • 数学。 random() 不是随机的。

标签: javascript angular date typescript random


【解决方案1】:

考虑一个服务器准备 3 个报价的方案:一个用于昨天、今天和明天。每个新的一天,昨天被删除,新的明天被添加。这样一来,客户的报价就可以在客户当地时间午夜过后更改,并且每个人都可以在当地同一天看到相同的报价。

地球上没有任何地方与 UTC 相差超过 14 小时,因此如果服务器基于 UTC 的密钥,每个客户端都会有适当数量的报价,并且整个报价数据库不会在每次更改时推送到每个客户端。

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));

【讨论】:

    【解决方案2】:

    不...等等... 如果您需要为每一天设置特定的报价,那是从报价列表中获取随机报价但在 eacb 24 hours, one day 上具有相同报价的另一种情况。 如果您有一个数组,您可能会使用 rand 函数和计数来获取数组的值总数。 这将在每次加载时返回一个值。 因此,还有另一个称为 srand 的函数。 如果您使用 srand,您将设置种子 .. 并且该种子将为 srand 播种。

    好的/

    因此,种子设置了 srand 结果.. srand 进行了随机化。 您也可以尝试随机播放功能。 IT 也使用种子。

    现在,您需要找到一个用作种子的值,并且您需要在 24 小时间隔内更改该数字。

    要使用区间,需要一个参考值。可以使用服务器时间和用户代理时间。

    如果您使用种子 '42',您将得到与 srand 相同的结果。

    检查一下: 假设您有一个 42 引号列表。 首先创建数组,设置种子变量,获取值。

    $numbers = range(1,42); $种子=地板(时间()/ 86400); 种子的值由服务器 unix 时间戳设置,其时区无关 (=UTC) 。 根据需要一天的间隔,使用 86400 值计算,一天的总秒数。 随机化数组 洗牌($数字); 并回显第一个结果。 让我们使用 200 个引号列表:

    $quoteslist= range(1,200);
    $seed = floor(time()/86400);
    echo $seed;
    
    $resultado = $quoteslist;
    $seed = floor(time()/86400);
     shuffle($resultado);
    echo $resultado[$i];
    

    time() 返回的值,时间戳,改为 18846,即今天的种子。

    然后,使用该值作为种子来打乱列表。

    获取第一个结果。

    // 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];
    

    【讨论】:

      【解决方案3】:

      您可以采取的一种方法是通过localStorage 在客户端上保存当前日期。在您的组件中,检查我们的 localStorage 中是否有 currentDay 键,如果没有创建它,请将 currentDay 值和 qotd 保存在对象内部。

      下次重新加载组件时,您应该已经在 localStorage 中分配了一个 qotd,因此我们要做的是检查保存在 localstorage 中的日期和我们生成的当前日期。如果它们不同,我们就知道这一天已经改变了。

        //PSUEDOCODE (haven't tested, but should give you a good idea)
        function(){
          this.qotd = this.quotes[Math.floor(Math.random() * this.quotes.length)];
      
          if(!window.localStorage.getItem('todayDate')){    
              let currentDay = new Date().getDay();
              let storageItem = JSON.stringify({
                currentDay,
                qotd: this.qotd
              })
              window.localStorage.setItem('currentDay',storageItem)
            } 
            else {
              var existingQOTD = JSON.parse(window.localStorage.getItem('todayDate'));
              let currentDay = new Date().getDay();
              if(existingQOTD.currentDay !== currentDay){
              let storageItem = JSON.stringify({
                currentDay,
                qotd: this.qotd
              })
                window.localStorage.setItem('currentDay', storageItem)
              }
      
            }
        }
      

      【讨论】:

      • 虽然我喜欢这种方法,但它实际上并不起作用。现在,通过上述实现,每次安装组件时都会加载一个新的报价,而不是每天一次。目前正在研究解决方案。
      • 本地存储?也许您应该专注于更改报价,而不是检查日期是否更改。在保存日期的情况下,每个用户每天都会看到不同的报价......并且不会是“当天”的报价......查看我的解决方案,使用 unix 时间戳生成种子并提供 srand 函数。 . 它的 php ......但是你可以在 javascript 上做同样的事情。
      猜你喜欢
      • 1970-01-01
      • 2022-01-21
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2017-05-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      相关资源
      最近更新 更多