【问题标题】:Search within a decimal range在小数范围内搜索
【发布时间】:2015-03-18 22:12:22
【问题描述】:
var a = {28.82:0, 28.91:0, 29.11:0, 30.11:0, 32.22:0, 32.23:0, 32.24:0};

function check(range) // range = 28.90;
if (a[range]){
  // do stuff here... 
}

如您所见,在上述场景中,条件永远不会成立。我想编写一个逻辑,其中考虑到范围的 +/- 0.01 以检查数组内部。

我曾想过通过范围检查功能来驱动所有数组元素,但这太昂贵了。

有什么想法吗?

【问题讨论】:

  • 没有办法使用某个虚构范围内的浮点数作为对象属性的键,它要么完全是键,要么不是键。您必须遍历所有键并检查它们是否在您的范围内,如果这太昂贵,您必须找出其他东西
  • 在 JavaScript 中,对象中不能有数字属性名称。数值可以是数字。我仍然不知道为什么您希望每个值都为 0。
  • 这些只是一些虚拟值。实际值会有所不同。
  • 你需要让问题更容易理解。

标签: javascript logic


【解决方案1】:

让我们看看我是否理解正确。
您需要定义一个容差:

var a = [28.82, 28.91, 29.11, 30.11, 32.22, 32.23, 32.24];

function check(range) { // range = 28.90;
  for (var i = 0; i < a.length; i++) {  
    if (Math.abs(a[i] - range) <= 0.01) {
      // do stuff here... 
    }
  }
}

a[i] - range 将产生您正在寻找的值和数字之间的差异。 0.01 是设置容差。

【讨论】:

  • 感谢您的回答。但这需要遍历整个对象。这会很贵。
  • 你一直说贵,但你知道javascript的运行速度吗?
  • 这是一个有代表性的数据集。实际数据会大得多,而且这种操作会经常发生。
【解决方案2】:

也许我误会了,但你不能这样做吗?

var a = {28.82:"a", 28.91:"b", 29.11:"c", 30.11:"d", 32.22:"e", 32.23:"f", 32.24:"g"};

function check(range){
    if (a[range] || a[range+0.01] || a[range-0.01]){
          // do stuff here... 
    }
}

还是您担心的方法太贵?

请注意,如果a[range] 处的值等于零或假,则逻辑检查if(a[range]) 将返回假。如果您希望代码在属性存在时运行,无论其值如何,您都需要稍微修改您的条件以解决这些边缘情况。

编辑:正如@SaniHuttunen 在 cmets 中指出的那样,您可以使用 if(a[range] !== undefined) 完成此操作

function check(range){
    function propExists(key){
        return a[key] !== undefined;
    }
    if (propExists(range) || propExists(range+0.01) || propExists(range-0.01){
        // do stuff here... 
    }
}

【讨论】:

  • 你可以只做a[key] !== undefined
  • facepalm ...好电话!
  • 但是这里有一个问题:有些值不能用双精度浮点数正确表示。即:28.83 - 0.01 = 28.819999999999997。那将无法通过测试。你仍然需要宽容。
  • 你可以做的是Math.round((range - 0.01)*100)/100(和Math.round((range + 0.01)*100)/100)。这将在减法(或加法)后将值四舍五入到小数点后 2 位。这将减轻算术精度误差。然而,这对于 OP 来说可能“太贵了”。
【解决方案3】:

知道它位于哪两个元素之间会有帮助吗?

var a = [28.82, 28.91, 29.11, 30.11, 32.22, 32.23, 32.24];

function check(arr, range) {
    var match = [];
    arr.reduce(function(prev, curr){
        if ( prev <= range && range <= curr ) { match = [prev, curr]; }
        return curr;
    })
    return match;
}

console.log(check(a, 30.90));
// [30.11, 32.22]

JSFiddle 演示。

【讨论】:

    猜你喜欢
    • 2019-08-12
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    相关资源
    最近更新 更多