2013-06-06 10 views
5

以下のコードでは、長い時間がかかります。JavaScriptの配列を効率的にフィルタリングする方法

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

でこれを(フィルター)を達成するためにとにかくあり秒ですか?

+1

私は答えを知らないが、私は答えにかなり興味がある。 – Qpirate

+0

は要素数の関係は常に同じですか? ( 'dtTypes.rows.length' <' 'dtObjects.Rows.length' <' dtColumns.Rows.length') –

+0

いいえ。長さは任意です。 –

答えて

3

あなたの最後のループの前に、あなたの最初の条件を条件付けが、抽象的で、これはありますどのように私は解決策を見るかもしれないか

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

まず、条件が一致したときに休憩を入れなかった。条件が合致した後に続行する必要はありません。

あなたは1つのことを行うことができます。あなたの条件として(dtObjects.Rows[i].Id == dtColumns.Rows[j].Id) && (dtColumns.Rows[j].xtype == dtTypes.Rows[k].xtype)私はあなたにこの論理を教えています。

最初のループdtObjectsとdtColumnsを確認し、条件dtObjects.Rows[i].Id == dtColumns.Rows[j].Idを確認します。どんなものでものIDはと一致しています。"jの値"新しい配列(Idが一致したときに覚えておいてください)。

このループを実行すると終了します。 newArrayとdtTypesにもう一度ループしてください。このようにして状態を確認してください。 "dtColumns[newArray[k]].xtype == dtTypes.Rows[l].xtype"

さらにもう一つは、より多くのカウントを持つ外側のループとしてオブジェクトを保つことです。

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

      } 

      } 
     } 

私はちょうど私たちは多くを行うことができないであろう任意のサンプルデータアウトでは、これはそれが「少し」速くなります

0

これはかなりのスピードを与えます。各行に対応する一致する列の数を知る必要があります。それがちょうど1つであれば、一度一致したループも解除できます。

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 
         }); 
         break; 
        } 
       } 
      } 
     } 
    } 
1

まず、idでdtObjectsとdtColumsの両方を並べ替えることができます。

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

あなたはIDを使用してインデックスオブジェクトを作成することによってこれを行うことができます。

var table = new Array(), 
    orows = dtObjects.Rows, 
    crows = dtColumns.Rows, 
    crowsIndex = {}, 
    types = dtTypes.Rows, 
    typesIndex = {}; 

for (var j = 0; j < crows.length; j++) { 
    crowsIndex[crows[j].Id] = crows[j]; 
} 

for (var k = 0; k < types.length; k++) { 
    typesIndex[types[k].xtype] = types[k]; 
} 

for (var i = 0; i < orows.length; i++) { 
    var rID = orows[i].Id; 
    if (crowsIndex[rID]) { 
     var xType = crowsIndex[rID].xtype; 
     if (typesIndex[xType]) { 
      table.push({ 
       TableName: orows[i].Name, 
       Type: orows[i].type, 
       ColumName: crowsIndex[rID]].Name, 
      DataType: typesIndex[xType].Name, 
      Length: crowsIndex[rID].Length 
      }); 
    } 
} 

これはテストされていないため、必要な最終的な解決策ではないかもしれませんが、開始には役立ちます。テストするサンプルデータを提供してください。

1

これはArunの答えに似ています(ただし、おそらくもっと簡単です)。

速度を向上させるためにメモリ使用量を少し増やしたい場合は、チェック対象のオブジェクトのハッシュを作成することができます。

ハッシュでの存在を確認することは、各列IDを反復して比較するよりもかなり高速です。これを利用するには、型コレクションと列コレクションの両方のハッシュを作成してから、ハッシュ内の存在をチェックするだけです。

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

for(var i =0; i< dtObjects.Rows.length; i++) { 
    var typesObj, columnObj = columnsHash[dtObjects.Rows[i].Id]; 
    if (columnObj && (typesObj = typesHash[columnObj.xtype])) { 
    table.push({ 
     TableName : dtObjects.Rows[i].Name, 
     Type: dtObjects.Rows[i].type, 
     ColumName: columnObj.Name, 
     DataType: typesObj.Name, 
     Length : columnObj.Length 
    }); 
    } 
} 

注:私は何かが欠けていない限り、私は実際には、明らかに、コードをテストしていませんが、理論的には、これは動作するはずです。

関連する問題