所以我有一个用于检索会员费率的电子表格,列是Age,Duration&率。您只需查看年龄列以查找客户的年龄,然后当您发现该年龄时,您将继续向下以使其与正确的持续时间相匹配,那么在最后一列中将是费率。 (非常)小版本可能看起来像这样;
Age,Duration,Rate
18,10,1.33
18,11,1.5
18,12,1.8
19,10,1.4
19,11,1.65
19,12,1.88
20,10,1.48
20,11,1.73
20,12,1.98
所以19岁的人,持续时间11的比率是1.65。年龄在20岁,持续时间为12岁的人的比率为1.98 - 很容易!
我的问题是两个部分,我想将其转换为一个网页,其中有人输入年龄和持续时间来检索费率。我非常确定我最好的选择是像这样的二维数组;
var array = [[18,10,1.33],[18,11,1.5],[18,12,1.8] .. and so on];
还有更好的选择吗?
第二个问题是如何最好地迭代二维数组(如果这最终成为最佳解决方案)?正如我之前提到的,我需要能够进行基于两个标准搜索的返回率的迭代。我相信这将包括一个两部分的迭代,但迭代对我来说是一个弱点,试图掌握在循环中的位置,我的迭代只是大脑融化。我认为它看起来像是这样;
for (var i = 0; i < array.length; i++){
for (var j = 0; j < array[i].length; j++){
//Do something... I think something like this
If array[][j] == ageImLookingFor && array[][j+1] == durationImLookingFor
then return array[][j+2] (which is the rate)
}
}
任何帮助,建议或想法我都会非常感激
答案 0 :(得分:2)
比使用数组更好的选择是使用对象(或Map
),其属性(键)对应于年龄和持续时间的有效组合,通过该键有效地索引数据:
var list = {
'18_10': { age: 18, duration: 10, rate: 1.33 }
'18_11': { age: 18, duration: 11, rate: 1.5 },
'18_12': { age: 18, duration: 11, rate: 1.8 },
// .. and so on
};
这样你就不必遍历一个数组(参见你的问题#2),但考虑到年龄和持续时间(假设在具有这些名称的变量中),你可以写这个来获得匹配的项目:
var item = list[age + '_' + duration];
当然,您应该检查年龄和持续时间是否为有效整数,并且项可以是undefined
时这个组合是未知的。
这是一个简单的代码段(没有任何检查),您可以使用它来构建您的Web表单。它从具有数据的数组构建上述对象。
// Data in array -- will be keyed later
var arr = [
{ age: 18, duration: 10, rate: 1.33 },
{ age: 18, duration: 11, rate: 1.5 },
{ age: 18, duration: 12, rate: 1.8 },
{ age: 19, duration: 10, rate: 1.4 },
{ age: 19, duration: 11, rate: 1.65 },
{ age: 19, duration: 12, rate: 1.33 },
{ age: 20, duration: 10, rate: 1.48 },
{ age: 20, duration: 11, rate: 1.73 },
{ age: 20, duration: 12, rate: 1.98 },
];
// Build map, keyed by age/duration. It will look like:
// {
// '18_10': { age: 18, duration: 10, rate: 1.33 },
// '18_11': { age: 18, duration: 11, rate: 1.33 },
// ...etc
// }
mapByAgeDuration = {};
for (var i=0; i < arr.length; i++) {
mapByAgeDuration[arr[i].age + '_' + arr[i].duration] = arr[i];
}
// Fast retrieval function:
function getItemFor(age, duration) {
return mapByAgeDuration[age + '_' + duration];
}
// I/O
var button = document.getElementById('findRate');
var inputAge = document.getElementById('age');
var inputDuration = document.getElementById('duration');
var outputRate = document.getElementById('rate');
button.onclick = function() {
var age = inputAge.value;
var duration = inputDuration.value;
// Retrieve item for this age and duration
var item = getItemFor(age, duration);
// Output rate
outputRate.textContent = item !== undefined ? item.rate
: 'not a valid combination';
}
Age (18 - 20): <input id="age"><br>
Duration (10 - 12): <input id="duration"><br>
<button id="findRate">Find Rate</button><br>
Rate: <span id="rate"></span><br>
答案 1 :(得分:1)
Q1:您可以使用哈希表进行查找。
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
data.forEach(function (a) {
object[a[0]] = object[a[0]] || {};
object[a[0]][a[1]] = a[2];
});
// usage
document.write(object[19][11] + '<br>');
document.write(object[20][12] + '<br>');
document.write('<pre>' + JSON.stringify(object, 0, 4) + '</pre>');
&#13;
Q2:Array#some()
如果您已对数据进行排序,则可以插入短路,如果值大于此值。
var data = [[18, 10, 1.33], [18, 11, 1.5], [18, 12, 1.8], [19, 10, 1.4], [19, 11, 1.65], [19, 12, 1.88], [20, 10, 1.48], [20, 11, 1.73], [20, 12, 1.98]],
object = {};
function getValue(p1, p2) {
var result;
data.forEach(function (a) {
if (a[0] === p1 && a[1] === p2) {
result = a[2];
return true;
}
// short circuit for not found values
return a[0] > p1;
});
return result;
}
// usage
document.write(getValue(19, 11) + '<br>');
document.write(getValue(20, 12) + '<br>');
&#13;
答案 2 :(得分:1)
另一种方法是利用array.filter
函数。
您必须将数据重塑为对象数组:
var rates = [
{'age':'18','duration':'10','rate':'1.33'},
{'age':'18','duration':'11','rate':'1.5'},
{'age':'19','duration':'12','rate':'1.8'}
];
function filterRate(item){
if(item.age == this.age && item.duration == this.duration)
return item;
}
function getRateByAgeDuration(age, duration){
res = null;
try{
res = rates.filter(filterRate, {'age':age, 'duration':duration})[0].rate;
}
catch(ex){ console.log(ex);}
return res;
}
document.write(getRateByAgeDuration('18', '10'));
答案 3 :(得分:1)
这取决于。如果使用哈希值,平均时间为O(1),但最坏情况下为O(n)。
如果您希望优化最坏情况,可以使用二分搜索在平均和最差情况下实现O(lg n)。
function binarySearch(array, data, from=0, to=array.length) {
if(from >= to) return -1; // not found
var m = Math.floor((from+to)/2);
for(var i=0; i<data.length; ++i) {
if(data[i] < array[m][i]) return binarySearch(array, data, from, m);
if(data[i] > array[m][i]) return binarySearch(array, data, m+1, to);
}
return m;
}
var idx = binarySearch(array, [18,12]);
if(idx > -1) array[idx];