Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient way of filtering arrays in javascript

Tags:

javascript

Below code takes long lots of minutes;

var table = new Array();
for(var i =0; i< dtObjects.Rows.length; i++)
        {
            for(var j=0; j< dtColumns.Rows.length; j++)
            {
                for(var k=0; k< dtTypes.Rows.length; k++)
                {
                  if((dtObjects.Rows[i].Id == dtColumns.Rows[j].Id) && (dtColumns.Rows[j].xtype == dtTypes.Rows[k].xtype))  

                      table.push({
                          TableName : dtObjects.Rows[i].Name,
                          Type:  dtObjects.Rows[i].type,
                          ColumName:  dtColumns.Rows[j].Name,
                          DataType: dtTypes.Rows[k].Name,
                          Length : dtColumns.Rows[j].Length
                      });
                }
            }
        }

dtObjects.Rows.length = 900

dtColumns.Rows.length = 1500

dtTypes.Rows.length = 30

Is there anyway to achieve (filter) this in seconds?

like image 417
Mehmet Ince Avatar asked Jun 06 '13 08:06

Mehmet Ince


People also ask

How do you filter an array in JavaScript?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.

Which is faster array filter or forEach?

Using forEach() for multi-step manipulation is about twice as fast as chaining methods like filter() and map() .

Which is faster filter or for loop JavaScript?

To our surprise, for-loops are much faster than the Array. filter method. To be precise, the Filter method is 77% slower than for loop.


4 Answers

With out any sample data we won't able to do much, but in an abstract this is how I might look at a solution

var table = new Array();

var dtObjectMap = {}, dtColumnMap = {};
for (var i = 0; i < dtObjects.Rows.length; i++) {
    dtObjectMap['id-' + dtObjects.Rows[i].Id] = dtObjects.Rows[i];
}

for (var j = 0; j < dtColumns.Rows.length; j++) {
    if (!dtColumnMap[dtColumns.Rows[j].xtype]) {
        dtColumnMap[dtColumns.Rows[j].xtype] = [];
    }
    dtColumnMap[dtColumns.Rows[j].xtype].push(dtColumns.Rows[j]);
}

var dtObject, dtColumn, dtType, dtCXtypes;
for (var k = 0; k < dtTypes.Rows.length; k++) {
    dtType = dtType.Rows[i], dtCXtypes = dtColumnXtypes[dtType.xtype];
    if (dtCXtypes && dtCXtypes.length) {
        for (var l = 0; l < dtCXtypes.length; l++) {
            dtColumn = dtCXtypes[l];
            dtObject = dtObjectMap['id-' + dtColumn.id];
            if (dtObject) {
                table.push({
                    TableName : dtObject.Name,
                    Type : dtObject.type,
                    ColumName : dtColumn.Name,
                    DataType : dtType.Name,
                    Length : dtColumn.Length
                });
            }
        }
    }
}
like image 169
Arun P Johny Avatar answered Sep 24 '22 20:09

Arun P Johny


var table = new Array();
for(var i =0; i< dtObjects.Rows.length; i++)
        {
            for(var j=0; j< dtColumns.Rows.length; j++)
            {
                if(dtObjects.Rows[i].Id == dtColumns.Rows[j].Id){
                    for(var k=0; k< dtTypes.Rows.length; k++)
                {
                  if(dtColumns.Rows[j].xtype == dtTypes.Rows[k].xtype) 

                      table.push({
                          TableName : dtObjects.Rows[i].Name,
                          Type:  dtObjects.Rows[i].type,
                          ColumName:  dtColumns.Rows[j].Name,
                          DataType: dtTypes.Rows[k].Name,
                          Length : dtColumns.Rows[j].Length
                      });
                }

             }

            }
        }

I just conditioned your first condition before your last loop this will make it "little bit" faster

like image 26
Muhammad Bekette Avatar answered Sep 21 '22 20:09

Muhammad Bekette


First you can sort both dtObjects and dtColums by id:

function sortById(a,b){
  return (a.id>b.id)?1:(a.id<b.id)?-1:0;
}
dtOjbects.Rows.sort(sortById);
dtColumns.Rows.sort(sortById);

var table = new Array(),
j=0,i=0,
colLen=dtColumns.Rows.length,
objLen=dtObjects.Rows.length,
typLen=dtTypes.Rows.length,
tmpMatch=[];
for(i =0; i< objLen; i++){
  while(j<colLen||dtObjects.Rows[i].id>dtColumns.Rows[j].id){
    if(dtObjects.Rows[i].id===dtColumns.Rows[j].id){
      tmpMatch.push([i,j]);
    }
    j++;
  }
}
for(i=0;i<tmpMatch.length;i++){
  for(j=0;j<typLen;j++){
    if(dtColumns.Rows[tmpMatch[i][1]].xtype == dtTypes.Rows[j].xtype){
      table.push({
        TableName : dtObjects.Rows[tmpMatch[i][0]].Name,
        Type:  dtObjects.Rows[tmpMatch[i][0]].type,
        ColumName:  dtColumns.Rows[tmpMatch[i][1]].Name,
        DataType: dtTypes.Rows[j].Name,
        Length : dtColumns.Rows[tmpMatch[i][1]].Length
    }
  }
}
like image 32
HMR Avatar answered Sep 23 '22 20:09

HMR


First of all you did not put a break when your condition matches. there is no need to go continue after matching condition.

You can do one thing. As per your condition (dtObjects.Rows[i].Id == dtColumns.Rows[j].Id) && (dtColumns.Rows[j].xtype == dtTypes.Rows[k].xtype) I am telling you this logic.

First loop dtObjects and dtColumns and check for condtion dtObjects.Rows[i].Id == dtColumns.Rows[j].Id. Whatever id's are matching put that "j value" new array (do not forget to put a break when Id match).

Once you done with this loop. Take one more loop for newArray and dtTypes. Check your condition in this manner "dtColumns[newArray[k]].xtype == dtTypes.Rows[l].xtype"

One more thing, keep the object as a outer loop who has more count.

like image 39
alok_dida Avatar answered Sep 21 '22 20:09

alok_dida