簡體   English   中英

在Javascript中重新創建查找表

[英]Recreating a lookup table in Javascript

因此,我有一個用於檢索會員費率的電子表格,這些列是“年齡”,“持續時間”和“費率”。 您只需查看“年齡”列即可找到客戶的年齡,然后當您發現該年齡時,便會繼續降低以使其與正確的“持續時間”相匹配,然后在最后一列中將是費率。 一個(非常小的)版本可能看起來像這樣;

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)
  }
}

任何幫助,建議或想法,我將非常感謝

與使用數組相比,更好的選擇是使用具有屬性(鍵)的對象(或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> 

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>'); 

問題2:帶有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>'); 

另一種方法是利用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')); 

這取決於。 如果使用哈希,則平均時間為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];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM