1

I want to return an array when one of the elements matches an item within an array.

Is the below code the fastest way to loop through an array when a value matches in a javascript array of arrays?

Note : Welcome any suggestions to modify the variable relatedVideosArray to make it a different data structure for better performance.

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];                   
        }               
      }
    }       
}

Update: I initially thought of making a key of video ids and values as all the related ids, but I want to display the key as well as all the related ids if any of the ids within the value array are clicked. Hope this helps to explain the constraint I have.

3
  • I might be missing something, but why do you need to create tempStoreArray? Why not just loop through relatedVideosArray[i]? Commented Jul 13, 2011 at 23:29
  • It makes the if statement after it a little bit easier to read, but it's not crucial. Commented Jul 13, 2011 at 23:38
  • If you really want lean, speedy code, remove the unnecessary variables. relVideosLen is not used at all. getCurrentId is redundant since you could just use videoClicked directly. I'm not sure what impact tempStoreArray has on speed, but to my eye it makes it harder to read, not easier - in any case there's no need to assign it an initial value since that value is never used. Commented Jul 14, 2011 at 1:06

3 Answers 3

1

Modern day browsers support Array indexOf.

For the people saying the array indexOf is slower, basic tests on speed.

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

Two possible solutions:

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);
Sign up to request clarification or add additional context in comments.

4 Comments

Which just loops over the array like in the question...except the sample code above uses the equality operator and at the link you gave they use the identity operator.
And in addition, not supported prior to IE 9.
The JavaScript indexOf is super fast than doing a for/while loop. Test it out if you do not believe me.
Since we're going for speed, wouldn't it be safer to get the arrayCount prior to the for loop instead of using array.length IN the for loop. For huge arrays, the JS engine will have to find length for each iteration.
1

I believe so if you keep your current structure. Unless you have a way of 'flattening' the array first, so that rather than being nested, there is simply one array with all the values. If this is out of your control or impractical, then you have no other choice than to iterate over every element and its elements.

Otherwise, would you be able to add the values to a map? The current video id would be the key, and the value would be the list of related videos.

Comments

1

If you have control over the data structure then I highly recommend changing it to something more amenable to the type of searches you are performing. First thing that comes to mind is an array of associative arrays. Each of your video arrays would be keyed with the video id ( set the value to anything you want ). That would make your search O(n), where n = the total number of video lists you have.

I'll post some code for this when I get in front of the computer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.