计算循环变量的最近值

Calculate the nearest value on a circular variable

我有一个问题,一天 24 小时有 3 次。为了简单起见,我可以使用十进制表示:

a) 23:45 (23.75)

b) 11:30 (11.50)

c) 00:15 (00.25)

我想知道,对于每个时间,哪个时间最近。

var closestTime = 24
var closestActualTime = 0;

for (var i = 0; i < times.length; i++) {
  if (times[i].time == this.time) continue;

  var temp = Math.abs(this.time - times[i].time)

  if (temp < closestTime) {
    closestTime = temp;
    closestActualTime = times[i].time;
  }
}

我的问题是 23:45 和 00:25 实际上非常接近,但我不知道如何处理具有模类型的变量

循环次数。

尝试 delta 时间的组合,偏移 24 小时。

选择最小的增量时间。

var times = [23.75, 11.50, 3, 6, 7];
/**
 * timeClosestTo
 *
 * @param {number} time
 * @returns {number}
 */
function timeClosestTo(time) {
    //Distance variable to compare against
    var distance = 100;
    //Hours in a day
    var day = 24;
    //Current best
    var best = null;
    //Test against all times
    for (var i = 0; i < times.length; i++) {
        //Find best score based upon day
        var d = Math.min(Math.abs((times[i]) - (time)), Math.abs((times[i] + day) - time), Math.abs((times[i]) - (time + day)), Math.abs((times[i] + day) - (time + day)));
        //If best found distance yet, set best to current
        if (d < distance) {
            best = times[i];
            distance = d;
        }
    }
    //Return best
    return best;
}
console.log("times to deal with:",times.join(", "));
console.log("closest to 1:", timeClosestTo(1), "closest to 11:", timeClosestTo(11), "closest to 5:", timeClosestTo(5));

我建议用这些对构建一个列表,然后计算差值。

区别在于 pairs 数组中的第三个元素。

基本上你需要检查增量,如果它大于 12 小时,取 24 和增量的差值。

delta = Math.abs(aa - bb);

if (delta > 12) {
    delta = 24 - delta;
}

function combination(array, size) {
    function c(part, start) {
        var i, l, p;
        for (i = start, l = array.length + part.length + 1 - size; i < l; i++) {
            p = part.slice();
            p.push(array[i]);
            p.length < size ? c(p, i + 1) : result.push(p);
        }
    }

    var result = [];
    c([], 0);
    return result;
}

function timeDelta(a, b) {
    function decimalTime(s) {
        var p = s.split(':');
        return +p[0] + p[1] / 60;
    }

    function padZero(v) {
        return (v < 10) ? '0' + v : String(v);
    }

    var aa = decimalTime(a),
        bb = decimalTime(b),
        delta = Math.abs(aa - bb);

    if (delta > 12) {
        delta = 24 - delta;
    }
    return padZero(Math.floor(delta)) + ':' + padZero(Math.round(60 * (delta - Math.floor(delta))));
}

var times = ['23:45', '11:30', '00:15'],
    pairs = combination(times, 2);

pairs.forEach(function (a, i, aa) {
    aa[i][2] = timeDelta(a[0], a[1]);
});

console.log(pairs);
.as-console-wrapper { max-height: 100% !important; top: 0; }

从功能上讲,我会按如下方式完成这项工作

var times = [23.75,11.50,0.25],
    diffs = times.reduce((d,t1,i,a) => a[i+1] ? d.concat(a.slice(i+1)
                                                          .map(t2 => [t1,t2,[Math.min(Math.abs(t1-t2),24-Math.abs(t1-t2))]
                                                                                 .map(n => ~~n + ":" + (n%1)*60)[0]]))
                                              : d,[]);
console.log(diffs);