2013-06-06 9 views
5

Unten Code dauert lange viele Minuten;Effiziente Methode zum Filtern von Arrays in 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

Gibt es trotzdem zu erreichen (Filter) diese in Sekunden?

+1

ich weiß nicht die Antwort, aber ich bin ziemlich interessiert an einer Antwort. – Qpirate

+0

ist die Beziehung der Elemente immer gleich? ('dtTypes.rows.length' <' dtObjects.Rows.length' <'dtColumns.Rows.length') –

+0

nein. Längen sind beliebig. –

Antwort

3

Mit Daten aus jeder Probe, die wir viel nicht in der Lage zu tun, aber in einer abstrakten dies Wie ich eine Lösung betrachten könnte

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

Zuerst haben Sie keine Pause gemacht, wenn Ihre Bedingung übereinstimmt. es besteht keine Notwendigkeit, nach übereinstimmender Bedingung fortzufahren.

Sie können eine Sache tun. Gemäß Ihrer Bedingung (dtObjects.Rows[i].Id == dtColumns.Rows[j].Id) && (dtColumns.Rows[j].xtype == dtTypes.Rows[k].xtype) erzähle ich Ihnen diese Logik.

Erste Schleife dtObjects und dtColumns und Prüfung auf die Bedingung dtObjects.Rows[i].Id == dtColumns.Rows[j].Id. Was auch immer IDs übereinstimmen setzen Sie das "j-Wert" neues Array (vergessen Sie nicht, eine Pause zu setzen, wenn Id übereinstimmen).

Sobald Sie mit dieser Schleife fertig sind. Nehmen Sie eine weitere Schleife für newArray und dtTypes. Überprüfen Sie Ihren Zustand auf diese Weise "dtColumns[newArray[k]].xtype == dtTypes.Rows[l].xtype"

Noch eine Sache, halten Sie das Objekt als äußere Schleife, die mehr zählt.

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

      } 

      } 
     } 

ich konditioniert gerade Ihren ersten Zustand vor dem letzten Schleife dies macht es „wenig“ schneller

0

Dies wird erhebliche Geschwindigkeit geben. Wir müssen wissen, wie viele übereinstimmende Spalten für jede Zeile möglich sind. Wenn es nur einer ist kann man die Schleife auch einmal abbrechen.

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

Zuerst können Sie beide dtObjects und dtColums von id sortieren:

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

Sie diese Aufgabe durch die Schaffung Index tun können, mit 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 
      }); 
    } 
} 

Dies ist nicht getestet und möglicherweise nicht die endgültige Lösung, die Sie brauchen, aber wird Ihnen helfen, zu beginnen. Bitte liefern Sie Beispieldaten zum Testen.

1

Dies ist vergleichbar mit Aruns Antwort (wenn auch vielleicht einfacher).

Was Sie tun können, wenn Sie bereit sind, ein wenig mehr Speicher für erhöhte Geschwindigkeit zu handeln, erstellen Sie einen Hash der Objekte, gegen die Sie überprüfen werden.

Die Existenz in einem Hash zu überprüfen ist wesentlich schneller, als Its für jede Spalte zu durchlaufen und zu vergleichen, Zeile & Typ. Um dies zu nutzen, können Sie zunächst einen Hash der beiden Typen und der Spaltensammlungen erstellen, dann müssen Sie nur innerhalb des Hashes auf Existenz prüfen.

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

Anmerkung: Ich habe nicht wirklich den Code getestet, natürlich, aber dies sollte in der Theorie funktionieren, es sei denn ich etwas fehle.

Verwandte Themen