2011-07-13 73 views
1

我想在元素之一匹配數組中的某個元素時返回數組。通過數組循環的最快方式

下面的代碼是當數組在JavaScript數組中匹配時循環訪問數組的最快方法嗎?

注意:歡迎您提出修改變量relatedVideosray的建議,使其成爲不同的數據結構以獲得更好的性能。

var relatedVideosArray = [ 

["1047694110001"], 
["1047694111001", "1019385098001","1020367665001","1020367662001", "1019385097001", "1020367667001"], 
["1040885813001"], 
["1019385094001", "1019385096001"], 
["952541791001", "952544511001", "952544512001", "952544508001", "952541790001","952580933001", "952580934001", "1051906367001"]           

] 


function getRelatedVideos(videoClicked){ 

    var tempStoreArray = [];  
    var getCurrentId = videoClicked;  
    var relVideoslen = relatedVideosArray.length; 

    for(var i in relatedVideosArray) { 
     tempStoreArray = relatedVideosArray[i]; 
     for(var j in tempStoreArray){    
       if(tempStoreArray[j] == getCurrentId){     
     return relatedVideosArray[i];     
     }    
     } 
    }  
} 

更新:我最初以爲製作的視頻ID和值作爲所有相關ID的關鍵,但我想顯示的按鍵以及所有相關的ID如果任何值陣列內的IDS被點擊。希望這有助於解釋我的約束。

+0

我可能會遺漏一些東西,但爲什麼你需要創建'tempStoreArray'?爲什麼不直接循環'relatedVideosArray [i]'? – norway28

+0

它使if語句稍微容易閱讀,但它並不重要。 – Igor

+0

如果您真的想要精益快速的代碼,請刪除不必要的變量。 'relVideosLen'完全沒有使用。 'getCurrentId'是多餘的,因爲你可以直接使用'videoClicked'。我不確定'tempStoreArray'對速度有什麼影響,但在我看來,它使得它更難以閱讀,而不是更容易 - 在任何情況下都不需要爲它指定初始值,因爲該值從未被使用過。 – nnnnnn

回答

2

現代的瀏覽器支持Array indexOf

對於說數組indexOf比較慢的人來說,基本的測試速度。

var values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]; 

console.time("for"); 
for(var i=0;i<1000;i++){ 
    for(var j=0;j<=values.length;j++){ 
    if(values[j]===20) break; 
    } 
}  
console.timeEnd("for"); 

console.time("reverse for"); 
for(i=0;i<1000;i++){ 
    for(var j=values.length-1;j>=0;j--){ 
    if(values[j]===1) break; 
    } 
} 
console.timeEnd("reverse for"); 


console.time("while"); 
for(i=0;i<1000;i++){ 
    var j=0; 
    while (j<values.length){ 
    if(values[j]===20) break; 
    j++; 
    } 
} 
console.timeEnd("while"); 


console.time("reverse while"); 
for(i=0;i<1000;i++){ 
    var j=values.length-1; 
    while (j>=0){ 
    if(values[j]===1) break; 
    j--; 
    } 
} 
console.timeEnd("reverse while"); 


console.time("indexOf"); 
for(var i=0;i<1000;i++){ 
    var x = values.indexOf(20); 
} 
console.timeEnd("indexOf"); 

console.time("toString reg exp"); 
for(var i=0;i<1000;i++){ 
    var x = (/(,|^)20(,|$)/).test(values.toString); 
} 
console.timeEnd("toString reg exp"); 

兩個可能的解決方案:

var relatedVideosArray = [ 

["1047694110001"], 
["1047694111001", "1019385098001","1020367665001","1020367662001", "1019385097001", "1020367667001"], 
["1040885813001"], 
["1019385094001", "1019385096001"], 
["952541791001", "952544511001", "952544512001", "952544508001", "952541790001","952580933001", "952580934001", "1051906367001"]           

] 

//var getCurrentId = "1019385098001"; 
var getCurrentId = "1040885813001"; 


console.time("indexOf"); 
var tempStoreArray = []; 
for(var i = relatedVideosArray.length-1; i>=0; i--){ 
    var subArr = relatedVideosArray[i]; 
    if(subArr.indexOf(getCurrentId)!==-1){ 
     tempStoreArray.push(subArr); 
    } 
} 
console.timeEnd("indexOf"); 
console.log(tempStoreArray); 




console.time("toString reg exp"); 
var tempStoreArray = []; 
var re = new RegExp("(,|^)" + getCurrentId + "(,|$)"); 
for(var i = relatedVideosArray.length-1; i>=0; i--){ 
    var subArr = relatedVideosArray[i]; 
    if(re.test(subArr.toString())){ 
     tempStoreArray.push(subArr); 
    } 
} 
console.timeEnd("toString reg exp"); 
console.log(tempStoreArray); 
+0

它只是像問題一樣在數組上循環......除了上面的示例代碼使用了相等運算符並且在您給它們的鏈接上它們使用了身份運算符。 – Paul

+0

另外,在IE 9之前不支持。 – Perception

+0

JavaScript indexOf比做for/while循環要快得多。如果你不相信我,試試吧。 – epascarello

1

我相信如果你保持現有的結構。除非你有辦法首先將數組「扁平化」,這樣纔不會嵌套,只有一個數組包含所有值。如果這超出了你的控制範圍或不切實際,那麼除了遍歷每個元素及其元素之外,別無選擇。

否則,你能夠將值添加到地圖?當前視頻ID將是關鍵,並且該值將是相關視頻的列表。

1

如果你有在數據結構控制的話,我強烈推薦它改變的東西更適合你執行搜索的類型。首先想到的是一組關聯數組。您的每個視頻陣列都會使用視頻ID進行鍵控(將值設置爲任何您想要的值)。這將使您的搜索O(N),其中N =您擁有的視頻列表總數。

我會在計算機前面發佈一些代碼。