【问题标题】:How to correctly use JavaScript indexOf in a date array如何在日期数组中正确使用 JavaScript indexOf
【发布时间】:2015-02-11 14:10:30
【问题描述】:

代码如下:

var collection = [new Date(2014, 11, 25), new Date(2014, 11, 24)];
var d=new Date(2014, 11, 24);

var idx= collection.indexOf(d);

我猜变量idx 的值应该是1,因为它是数组collection 中的第二个值。但事实证明是-1

这是为什么呢? JavaScript Date 类型有什么特别需要注意的地方吗?

这是一个sn-p:

(function() {

  var collection = [new Date(2014, 11, 25), new Date(2014, 11, 24)];
  var d = new Date(2014, 11, 24);

  var idx1 = collection.indexOf(d);

  var intArray = [1, 3, 4, 5];
  var idx2 = intArray.indexOf(4);

  $('#btnTry1').on('click', function() {
    $('#result1').val(idx1);
  });

  $('#btnTry2').on('click', function() {
    $('#result2').val(idx2);
  });
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Index:
<input type="text" id="result1" value="">
<button id="btnTry1">Find index in a date array</button>
<br />Index:
<input type="text" id="result2" value="">
<button id="btnTry2">Find index in a regular array</button>

【问题讨论】:

  • d 是 Date 的一个新实例,即使日期与索引 1 相同,但对象不同,因此结果为 -1。
  • 两个不同的实例永远不会相等。仅供参考,ES6 通过引入Array#findIndex 解决了这个问题,它接受一个回调进行比较:collection.findIndex(function(x) { return x.valueOf() === d.valueOf(); });

标签: javascript date indexof


【解决方案1】:

除非您将它们序列化,否则两个 对象 永远不会相等。幸运的是,日期很容易序列化为整数。

var collection = [new Date(2014, 11, 25), new Date(2014, 11, 24)],
    d = new Date(2014, 11, 24),
    idx;

idx = collection.map(Number).indexOf(+d); // 1
//              ^^^^^^^^^^^^         ^ serialisation steps

【讨论】:

  • 整洁!你的map+d 让我大开眼界。
  • 假设日期在像data = [{ date: Date 2018-09-15T00:00:00.000Z, pn: 55, other: "blah" },...]这样的对象数组中,地图等如何翻译?
【解决方案2】:

两个不同的对象永远不会彼此相等,即使它们具有相同的属性/值。这是该问题的前瞻性答案:

ECMAScript 6 引入了Array#findIndex,它接受比较回调:

var index = collection.findIndex(function(x) { 
    return x.valueOf() === d.valueOf(); 
});

Browser support isn't great yet though.

【讨论】:

    【解决方案3】:

    indexOf() 在这里不起作用...在前面的答案中已经很好地解释了...

    您可以为索引创建自己的查找。这是一个简单的示例,使用它们的 .getTime() 值比较日期...

    (function() {
    
      var collection = [new Date(2014, 11, 25), new Date(2014, 11, 24)];
      var d = new Date(2014, 11, 24);
    
      var idx1 = -1;
      collection.forEach(function(item, index){
        if(d.getTime() == item.getTime())
          idx1 = index;
      });
    
      var intArray = [1, 3, 4, 5];
      var idx2 = intArray.indexOf(4);
    
      $('#btnTry1').on('click', function() {
        $('#result1').val(idx1);
      });
    
      $('#btnTry2').on('click', function() {
        $('#result2').val(idx2);
      });
    })();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    Index:
    <input type="text" id="result1" value="">
    <button id="btnTry1">Find index in a date array</button>
    <br />Index:
    <input type="text" id="result2" value="">
    <button id="btnTry2">Find index in a regular array</button>

    【讨论】:

      【解决方案4】:

      这是因为您的“d”对象是不同的对象。换句话说:

      var d = new Date(2014, 11, 24);
      
      d === new Date(2014, 11, 24); // returns false
      

      你可以试试这个:

      var d = new Date(2014, 11, 24);
      var collection = [new Date(2014, 11, 25), d];
      
      var idx = collection.indexOf(d); // returns 1
      

      【讨论】:

      • 谢谢。现在我明白为什么了。但是查看日期值是否包含在数组中的正确方法是什么?
      【解决方案5】:
      Array.prototype.indexOfDate = function(date){
         for (var i = 0; i < this.length; i++){
            if (+this[i] === +date) return i;
         };
         return -1;
      };
      
      // then 
      var idx1 = collection.indexOfDate(d);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-22
        • 1970-01-01
        • 2013-12-09
        • 1970-01-01
        • 2018-05-12
        • 1970-01-01
        相关资源
        最近更新 更多