【问题标题】:pick new item from array every day每天从数组中挑选新项目
【发布时间】:2016-04-18 19:12:40
【问题描述】:

假设我有一个任意固定长度的数组,即它可以是 3、5、7 ... 最多 30。

我如何生成一个算法,如果我每天从数组中选择一个项目,它不应该在任何连续两天选择相同的项目索引。

注意:我没有能力存储前一天采摘的东西。

例如, 如果我的数组是 ["a", "b", "c", "d", "e", "f"]

有效的结果是 ["a", "b", "c", "d", "e", "f", "d", "a", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

无效的结果是

["a", "b", "c", "d", "e", "f", "a", "b", "b", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

注意上面连续的b

理想的结果是:在达到长度结束后整个数组完全旋转。

["a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

【问题讨论】:

  • 如果您希望它一整天都给您相同的结果,而与调用它的频率无关,那么我建议使用月份中的某天作为某种索引器。将其归结为适合您的数组,默认情况下您将获得每日唯一且递增的结果。
  • 您可以访问天数吗?您可以使用天数取模数组中的元素数作为要选取的元素的索引。否则,您可以将选取的元素与索引 0 处的元素交换,并始终从范围 [1, n - 1] 中选取元素,这样您就永远不会选取位置 0 上的前一个元素
  • 所以你想要一个(伪)随机序列并且它本身没有索引。正确的?每天选择一个(且相同的)索引。这个序列应该持续多长时间(多少天/月/年)?你必须能够从过去中挑选价值吗?
  • 对不起,没有看到完美旋转的部分。最简单的解决方案:arr[ Math.floor(Date.now()/86400000) % arr.length ]

标签: javascript arrays algorithm


【解决方案1】:

尝试使用 mod (%),这样数字永远不会超过数组长度。演示:

var array = ["a", "b", "c", "d", "e", "f"];
var output = [];
for (var day = 1; day < 365; day++) {
    output.push(array[day % array.length])
}
console.log(output);

【讨论】:

    【解决方案2】:
    var d = new Date();
    var n = d.getDay();
    var chr = String.fromCharCode(97 + n);
    

    每天运行此程序以生成序列中的下一个值。

    所以你的顺序是:

    a、b、c、d、e、f、g

    【讨论】:

      【解决方案3】:

      我使用模运算符制作了一个解决方案:%。不确定这是否正是您想要的,但它似乎工作正常。

      var items = ["a","b","c","d","e","f"];
      var day = new Date().getDay();
      
      console.log(items[day % items.length]);
      

      您大概可以将它放入一个函数中,或者根据您的喜好显示它。

      【讨论】:

        【解决方案4】:

        这很容易使用getDate 来完成,它返回当月的当前日期(1 - 31,具体取决于月份)。将此与模运算符结合使用可确保您始终以非连续顺序获得有效项目。

        function log(msg) {
          document.querySelector('pre').innerHTML += msg + '\n';
        }
        
        function logItem(items, date) {
          var index = (date.getDate() - 1) % items.length;
          var item = items[index];
          log(date.toDateString() + ' : ' + item);
        }
        
        function addDay(date) {
          date.setDate(date.getDate() + 1);
        }
        var items = ['a', 'b', 'c', 'd', 'e', 'f'];
        var day = new Date(2016, 0, 1);
        for (var i = 0; i < items.length * 3; i++) {
          logItem(items, day);
          addDay(day);
        }
        &lt;pre&gt;&lt;/pre&gt;

        这种精确实现存在一个问题:月底可能与月初具有相同的相对值。

        function log(msg) {
          document.querySelector('pre').innerHTML += msg + '\n';
        }
        
        function logItem(items, date) {
          var index = (date.getDate() - 1) % items.length;
          var item = items[index];
          log(date.toDateString() + ' : ' + item);
        }
        
        function addDay(date) {
          date.setDate(date.getDate() + 1);
        }
        var items = ['a', 'b', 'c', 'd', 'e', 'f'];
        var day = new Date(2016, 0, 30);
        for (var i = 0; i < 4; i++) {
          logItem(items, day);
          addDay(day);
        }
        &lt;pre&gt;&lt;/pre&gt;

        要处理这个问题,您可以determine how many days are in the month,确定您的开始和结束索引是否相同,如果是则更改一个。如何选择替代值取决于您。

        function log(msg) {
          document.querySelector('pre').innerHTML += msg + '\n';
        }
        
        function logItem(items, date) {
          // ---
          var daysInMonth = getDays(date);
          var day = date.getDate();
          var index = (day - 1) % items.length;
          if (day === daysInMonth && (day - 1) % items.length === 0) {
            // Change to a different item
            index = Math.floor(Math.random() * (items.length - 3)) + 2;
          }
          // ---
          var item = items[index];
          log(date.toDateString() + ' : ' + item);
        }
        
        function getDays(date) {
            return new Date(date.getYear(), date.getMonth() + 1, 0).getDate();
        }
        
        function addDay(date) {
          date.setDate(date.getDate() + 1);
        }
        var items = ['a', 'b', 'c', 'd', 'e', 'f'];
        var day = new Date(2016, 0, 30);
        for (var i = 0; i < 4; i++) {
          logItem(items, day);
          addDay(day);
        }
        &lt;pre&gt;&lt;/pre&gt;

        【讨论】:

          【解决方案5】:

          试试这样的

          var a = ["a", "b", "c", "d", "e", "f"],
            b = [],
            random;
          
          var i = function(val) {
            random = val[Math.floor(Math.random() * val.length)];
            (random != b[b.length - 1]) ? b.push(random): b.push('duplicate');
            console.log(b);
          }
          
          setInterval(() => {
            i(a)
          }, 1000);

          【讨论】:

          • 这根本没有考虑到这一天。如果此算法在程序连续几天的不同运行期间完成,则它可以在两天内产生相同的输出。
          • @Mike C 你是对的,我使用setInterval 只是为了演示目的
          猜你喜欢
          • 1970-01-01
          • 2014-03-20
          • 1970-01-01
          • 2021-08-19
          • 2021-04-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多