计算循环变量的最近值
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);
我有一个问题,一天 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);