我需要通过在基于两个值的表中查找结果来计算结果。表格是这样的:
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 交给客户端并让他们维护它 - 因此需要考虑可读性。
最佳答案
我建议为这个过程创建一个数据结构。这将涉及一个 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/