发现用JavaScript数组中最接近的日期 [英] Find closest date in array with JavaScript

查看:147
本文介绍了发现用JavaScript数组中最接近的日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这天的数组。每一天都是一个对象,例如:

{day_year:2012,day_month:08,DAY_NUMBER:03,DAY_NAME:星期一}

我还添加了一个时间戳属性,每一天的对象,请使用:

 函数convertDays(){
    VAR max_i = days.length;
    对于(VAR I = 0; I< max_i;我++){
        VAR tar_i =天[I]
        tar_i.timestamp =新的日期(tar_i.day_year,tar_i.day_month,tar_i.day_number);
    }
}

在阵列中的日子是任意的,所以没有真正的逻辑给他们。

现在我想找到最接近的两个日子对任何给定的日期。所以,如果有天数组包含


  • 2012年8月2

  • 2012年8月4

  • 2012年8月23日,

和我搜索2012年8月11日,我希望它回到2012年8月4日和2012年8月23日。

我一直在使用从另一个问题的答案试过了,看起来像这样:

 函数findClosest(A,X){
    VAR卤味,喜;
    对于(VAR I =则为a.length;我 - ;){
        如果(一个[1] - ; = X&放大器;及(LO ===未定义|| LO&下;一个由[i]))LO =一个由[i];
        如果(一个[Ⅰ]≥= X&放大器;及(喜===未定义||喜>一种由[i]))喜=一个由[i];
    }
    返回[LO,喜]
}

不过,这将返回不明

什么是最有效的(至少处理器/内存密集型的方式)来实现这一目标?

编辑:不过,怎么是这些结果怪

你能提供您code和数据的例子?

我现在用下面的生成日期的数组:

  VAR full_day_array = [];
为(变量I = 0; I&小于10;我++){
    变种D =新的日期();
    d.setDate(d.getDate()+ I);
    full_day_array.push({day_year:d.getFullYear()的toString(),day_month:(d.getMonth()+ 1)的ToString(),DAY_NUMBER:d.getDate()的toString()});
}

奇怪的部分是,使用下面的code,这仅适用于10日期或更短的数组。每当我使用11个或多个日期的数组,结果变成意外。

例如:使用15日期的数组,开始于2012年8月6日至8月21日,2012年如果我再调用 findClosest(full_day_array,新的日期(30/07/2012 ); ,你会希望它返回 {nextIndex:0,prevIndex:-1} 然而,它返回<$ C $。 C> {nextIndex:7,prevIndex:-1} 为什么

 函数findClosest(对象,testDate){
    VAR nextDateIndexesByDiff = []
        prevDateIndexesByDiff = [];    对于(VAR I = 0; I&LT; objects.length;我++){
        VAR thisDateStr = [对象[I] .day_month,对象[I] .day_number,对象[I] .day_year]。加入('/'),
            thisDate =新的日期(thisDateStr)
            curDiff = testDate - thisDate;        curDiff&LT; 0
            ? nextDateIndexesByDiff.push([我,curDiff])
            :prevDateIndexesByDiff.push([我,curDiff]);
    }    nextDateIndexesByDiff.sort(功能(A,B){返回[1]; B [1];});
    prevDateIndexesByDiff.sort(功能(A,B){返回一个[1]&GT; B [1];});
    VAR nextIndex;
    VAR prevIndex;    如果(nextDateIndexesByDiff.length&所述; 1){
        nextIndex = -1;
    }其他{
        nextIndex = nextDateIndexesByDiff [0] [0];
    }
    如果(prevDateIndexesByDiff.length&LT; 1){
        prevIndex = -1;
    }其他{
        prevIndex = prevDateIndexesByDiff [0] [0];
    }
    返回{nextIndex:nextIndex,prevIndex:prevIndex};
}


解决方案

这个工作,不管日期的数组是多久呢:

 函数newFindClosest(日期,testDate){
    = []之前变种;
    = []后变种;
    VAR最大= dates.length;
    对于(VAR I = 0; I&LT;最大;我++){
        VAR焦油=日期[I]
        VAR arrDate =新的日期(tar.day_year,tar.day_month,tar.day_number);
        // 3600 * 24 * 1000 =计算毫秒到几天,为清楚。
        变种的diff =(arrDate - testDate)/(3600 * 24 * 1000);
        如果(DIFF&0){
            before.push({差异:差异,指数:我});
        }其他{
            after.push({差异:差异,指数:我});
        }
    }
    before.sort(功能(A,B){
        如果(a.diff&LT; b.diff){
            返回-1;
        }
        如果(a.diff&GT; b.diff){
            返回1;
        }
        返回0;
    });    after.sort(功能(A,B){
        如果(a.diff&GT; b.diff){
            返回-1;
        }
        如果(a.diff&LT; b.diff){
            返回1;
        }
        返回0;
    });
    返回{datesBefore:之前,datesAfter:后};
}

I have an array with days in it. Each day is an object, for example:

{day_year: "2012", day_month: "08", day_number: "03", day_name: "mon"}

I have also added a timestamp attribute to each day object, by using:

function convertDays() {
    var max_i = days.length;
    for(var i = 0; i < max_i; i++) {
        var tar_i = days[i];
        tar_i.timestamp = new Date(tar_i.day_year, tar_i.day_month, tar_i.day_number);
    }
}

The days in the array are arbitrary, so there is no real logic to them.

Now I want to find the two closest days to any given date. So if the array with days contains

  • August 2, 2012
  • August 4, 2012
  • August 23, 2012

And I search for August 11, 2012, I want it to return August 4, 2012 and August 23, 2012.

I have tried using an answer from another question, that looks like this:

function findClosest(a, x) {
    var lo, hi;
    for(var i = a.length; i--;) {
        if(a[i] <= x && (lo === undefined || lo < a[i])) lo = a[i];
        if(a[i] >= x && (hi === undefined || hi > a[i])) hi = a[i];
    }
    return [lo, hi];
}

However, this returns unidentified.

What would be the most efficient (least processor/memory intensive way) to achieve this?

Edit: "However, how are those results "strange"? Could you provide an example of your code and data?"

I'm now using the following to generate an array of dates:

var full_day_array = [];
for(var i = 0; i < 10; i++) {
    var d = new Date();
    d.setDate(d.getDate() + i);
    full_day_array.push({day_year: d.getFullYear().toString(), day_month: (d.getMonth() + 1).toString(), day_number: d.getDate().toString()});
}

The strange part is, using the code below, this only works for an array of 10 dates or shorter. Whenever I use an array of 11 or more dates, the results become unexpected.

For instance: using an array of 15 dates, starting on August 6, 2012, to August 21, 2012. If I then call findClosest(full_day_array, new Date("30/07/2012"); you would expect it to return {nextIndex: 0, prevIndex: -1}. However, it returns {nextIndex: 7, prevIndex: -1}. Why?

function findClosest(objects, testDate) {
    var nextDateIndexesByDiff = [],
        prevDateIndexesByDiff = [];

    for(var i = 0; i < objects.length; i++) {
        var thisDateStr = [objects[i].day_month, objects[i].day_number, objects[i].day_year].join('/'),
            thisDate    = new Date(thisDateStr),
            curDiff     = testDate - thisDate;

        curDiff < 0
            ? nextDateIndexesByDiff.push([i, curDiff])
            : prevDateIndexesByDiff.push([i, curDiff]);
    }

    nextDateIndexesByDiff.sort(function(a, b) { return a[1] < b[1]; });
    prevDateIndexesByDiff.sort(function(a, b) { return a[1] > b[1]; });


    var nextIndex;
    var prevIndex;

    if(nextDateIndexesByDiff.length < 1) {
        nextIndex = -1;
    } else {
        nextIndex = nextDateIndexesByDiff[0][0];
    }
    if(prevDateIndexesByDiff.length < 1) {
        prevIndex = -1;
    } else {    
        prevIndex = prevDateIndexesByDiff[0][0];
    }
    return {nextIndex: nextIndex, prevIndex: prevIndex};
}

解决方案

This works, no matter how long the array of dates is:

function newFindClosest(dates, testDate) {
    var before = [];
    var after = [];
    var max = dates.length;
    for(var i = 0; i < max; i++) {
        var tar = dates[i];
        var arrDate = new Date(tar.day_year, tar.day_month, tar.day_number);
        // 3600 * 24 * 1000 = calculating milliseconds to days, for clarity.
        var diff = (arrDate - testDate) / (3600 * 24 * 1000);
        if(diff > 0) {
            before.push({diff: diff, index: i});
        } else {
            after.push({diff: diff, index: i});
        }
    }
    before.sort(function(a, b) {
        if(a.diff < b.diff) {
            return -1;
        }
        if(a.diff > b.diff) {
            return 1;
        }
        return 0;
    });

    after.sort(function(a, b) {
        if(a.diff > b.diff) {
            return -1;
        }
        if(a.diff < b.diff) {
            return 1;
        }
        return 0;
    });
    return {datesBefore: before, datesAfter: after};
}

这篇关于发现用JavaScript数组中最接近的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆