javascript - 二维查找表——如何在 javascript 中存储标题

标签 javascript multidimensional-array

我需要通过在基于两个值的表中查找结果来计算结果。表格是这样的:

     Bar  <10   20   30   40   50   60
    Foo
   <1.0   .14  .17  .22  .29  .31  .45
    1.1   .16  .18  .25  .32  .37  .51
    1.2   .19  .20  .29  .37  .41  .53
    1.3   .21  .22  .32  .44  .49  .59
    1.4   .25  .26  .34  .51  .52  .68
    1.5   .29  .31  .39  .53  .54  .71

其中顶部的数字是 Bar 值的范围(其中给定的数字是范围的顶端),左侧下方的数字是 Foo 值的范围。如果我得到 Bar = 24 和 Foo=1.3,查找答案将为 .32。 (当然,上面的数字是虚构的,真正的 table 大约是 25 X 25 大小。)

所有这些都必须在 javascript 中完成,包括存储查找值。

一种可能的方法是将值存储为哈希的哈希:

var lookup = { 1.0: {10:.14, 20: .17, 30:.22}); etc. etc.

其中外部值是 Foo 值,每个 Foo 值映射到一个对象,该对象将 Bar 值映射到答案。凌乱且难以阅读,但相当明确。

另一种方法是将值存储为数组的数组,并从其他地方获取索引。也就是说,我将值存储在顶部:

var BarColumns = [10, 20, 30, 50, 50, 60];

在旁边

var FooRows = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5];

当给定一些值时,我使用上面的列表将它们变成索引,然后使用这些索引在包含答案的二维数组中查找:

var lookup = [
  [.14, .17, .22, .29, .31, .45],
  [.16, .18, .25. .32, .37, .51],
  etc.
];

这与原始表格更接近,但没有标题,表格数据根本不是人类可读的,我认为这更难维护——尤其是当列发生变化时。

另一个选项—— super 显式,在每个对象中重复范围:

var lookup = [{foo:1.0, bar:10, result:.14}, {foo:1.0, bar:20, result: .17}, etc.];

这是非常明确的,但可能会很大,有 25 X 25 个值。

因此,我的问题是:存储原始表的最佳方式是什么,以便我可以使用它进行查找,并且它是人类可读和可维护的?我上面的想法之一?还是完全不同?

我应该添加的要点:1) 实际查找不会经常发生,所以我不太关心性能(在合理范围内),以及 2) 我从客户端,但最好的结果是,如果我可以将最终的 javascript 交给客户端并让他们维护它 - 因此需要考虑可读性。

最佳答案

jsFiddle Demo

我建议为这个过程创建一个数据结构。这将涉及一个 LookUp“类”,它将调解一组 DataPoint 对象,这些对象将包含一个范围、一个条形图和一个值。

数据结构

var Range = function(lower,upper){
 this.lower = lower;
 this.upper = upper;
};
var DataPoint = function(range,bar,value){
 this.range = range;
 this.bar = bar;
 this.value = value;
};
var LookUp = function(){
 this.DataPoints = [];   
};
LookUp.prototype.add = function(data){
 this.DataPoints.push(data);  
};

LookUp.prototype.load = function(BarColumns,FooRows,ValueColumns){
 ValueColumns = ValueColumns.split(" ").filter(Boolean);
 for( var n = 0; n < FooRows.length; n++ ){
  var range = 0;
  for( var i = 0 ; i < BarColumns.length; i++ ){
   var val = parseFloat(ValueColumns[(BarColumns.length * n) + i],10);
   var point = new DataPoint(new Range(range,BarColumns[i]),FooRows[n],val);
   this.add(point);
   range = BarColumns[i];
  }
 }   
};
LookUp.prototype.find = function(x,bar){
 for(var i = 0; i < this.DataPoints.length; i++){
  var point = this.DataPoints[i];
  if( x > point.range.lower && x < point.range.upper && point.bar == bar){
   return point.value;
  }
 }
};

示例数据

注意:valCols 字符串只是网格的复制粘贴。但是,这可以很容易地从 Excel 中重现。在每一行的末尾进行连接,然后在连接列的底部连接所有这些,它将与此处显示的 valCols 相同。

var BarColumns = [10, 20, 30, 50, 50, 60];
var FooRows = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5];
var valCols = ".14  .17  .22  .29  .31  .45 .16  .18  .25  .32  .37  .51 .19  .20  .29  .37  .41  .53 .21  .22  .32  .44  .49  .59 .25  .26  .34  .51  .52  .68 .29  .31  .39  .53  .54  .71";

设置

var lookup = new LookUp();
lookup.load(BarColumns,FooRows,valCols);

使用

console.log(lookup.find(24,1.3));//3.2
alert(lookup.find(24,1.3));//3.2

关于javascript - 二维查找表——如何在 javascript 中存储标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24088588/

相关文章:

javascript - 如何通过 Date 属性过滤对象数组,仅显示每天最后存储的对象?

javascript - 使用javascript的磁性光标移动

javascript - "Cannot set property of undefined",即使数组已经初始化

java - 如何在 Java 中比较两个二维数组?

c - 使用 for 循环的二维数组赋值

javascript - 带有 if 语句和 2-dim 数组 javascript 的嵌套 for 循环

javascript - Node.js 和依赖项管理

javascript - 如果通过 AJAX 修改 DOM,HTML 表单提交事件会丢失

javascript - 如何将 int 变量从 python 传输到 javascript?

algorithm - 是否有 OSS 或算法来计算许多 3D 对象所需的总 3D 空间?