2016-08-29 99 views
-2

假設我有一個稀疏數組,其值爲「foo」,賦值爲索引100,值「bar」賦值給索引130.我怎樣才能「舍入」任何給定的索引這樣它總是返回最近定義的索引的值?查找最接近給定索引的javascript稀疏數組索引

例如:如果我試圖獲得索引103的值,我應該得到「富」而不是未定義的。同樣,99的過低指數仍然應該給我「foo」,而115應該在指數130四捨五入到「bar」。

這應該完全獨立於(和無關)存儲在指數。

編輯:使用密集陣列和一個包圍搜索在 O(日誌(n))的時間解決 O(n)的時間。請注意,這要求將濃縮陣列從低到高排序。

var sparseArr = []; 
sparseArr[100] = "foo"; 
sparseArr[130] = "bar"; 
sparseArr[150] = "foobar"; 

var condensedArr = [100, 130, 150]; 

function roundGet(index) { 
    var mid; 
    var lo = 0; 
    var hi = condensedArr.length - 1; 
    while (hi - lo > 1) { 
    mid = Math.floor((lo + hi)/2); 
    if (condensedArr[mid] < index) { 
     lo = mid; 
    } else { 
     hi = mid; 
    } 
    } 
    if (index - condensedArr[lo] <= condensedArr[hi] - index) { 
    return sparseArr[condensedArr[lo]]; 
    } 
    return sparseArr[condensedArr[hi]]; 
} 

例在https://jsfiddle.net/xfevha56/

+0

你至少應該告訴我們你有什麼到目前爲止,一切是不是代碼編寫服務 –

+0

你會如何期待檢索這些值?本地數組索引器總是返回未定義的索引而沒有值... –

+0

@AdamBuchananSmith到目前爲止,我已經創建了一個單獨的非稀疏數組,它列出了所有佔用的索引(在本例中爲[100,130]),並使用了簡單的算法來遍歷第二個數組並找到最接近我的索引的數字。但是,它非常快速地增長效率(n^2次),所以我想找到更好的答案。 –

回答

0

你可以使用Array#some,其迭代只有非項目疏林。

function roundGet(index) { 
 
    var last = -Infinity, 
 
     value; 
 
    a.some(function (v, i) { 
 
     if (Math.abs(last - index) <= Math.abs(i - index)) { 
 
      return true; 
 
     } 
 
     value = v; 
 
     last = i; 
 
    }); 
 
    return value; 
 
} 
 

 
var a = []; 
 
a[100] = 'foo'; 
 
a[130] = 'bar'; 
 
a[150] = 'foobar'; 
 

 
console.log(roundGet(0)); // "foo" 
 
console.log(roundGet(99)); // "foo" 
 
console.log(roundGet(103)); // "foo" 
 
console.log(roundGet(115)); // "foo" 
 
console.log(roundGet(116)); // "bar" 
 
console.log(roundGet(186)); // "foobar" 
 
console.log(roundGet(1000)); // "foobar"

ES6

function roundGet(index) { 
 
    var last = -Infinity, 
 
     value; 
 
    a.some((v, i) => 
 
     Math.abs(last - index) <= Math.abs(i - index) || (value = v, last = i, false)); 
 
    return value; 
 
} 
 

 
var a = []; 
 
a[100] = 'foo'; 
 
a[130] = 'bar'; 
 
a[150] = 'foobar'; 
 

 
console.log(roundGet(0)); // "foo" 
 
console.log(roundGet(99)); // "foo" 
 
console.log(roundGet(103)); // "foo" 
 
console.log(roundGet(115)); // "foo" 
 
console.log(roundGet(116)); // "bar" 
 
console.log(roundGet(186)); // "foobar" 
 
console.log(roundGet(1000)); // "foobar"

0

你還沒談到瀏覽器支持什麼,所以這裏是使用一些數組操作功能(IE9 +)和ES2015功能箭頭語法的解決方案。

function findIndex(array, searchedIndex) { 
    return Object.keys(array) 
       .map(e => ({val: parseInt(e, 10), abs: Math.abs(parseInt(e, 10) - searchedIndex)})) 
       .reduce((min, e) => min[0].val > e.abs ? [{val: e.abs, i: e.val}] : min, [{val: Number.MAX_VALUE, i: -1}]) 
       .reduce((v, min) => min.val !== Number.MAX_VALUE ? array[min.i] : v, -1) 
} 

你可以試試Babel online REPL

0

您可能會這樣做;

function findCloseIndex(a,idx){ 
 
    return Object.keys(a) 
 
       .map(k => [k,Math.abs(k-idx)]) 
 
       .sort((a,b) => a[1] - b[1])[0][0]; 
 
} 
 

 
var arr = [], 
 
    close; 
 

 
arr[100] = "foo"; 
 
arr[130] = "bar"; 
 

 
close = arr[findCloseIndex(arr,125)]; 
 
console.log(close); 
 
close = arr[findCloseIndex(arr,78)]; 
 
console.log(close);