Mehrdimensionales Array sortieren

War auch schon in zahlreichen Threads im SELFHTML-forum ein heißes Thema, doch wie dort habe ich auch hier keine Antwort darauf gefunden.
Dass es in JS keine native Methode zum sortieren von Mehrdimensionalen Arrays gibt, ist mir klar. Ich hab nach über 2 Stunden Tüftelei eine kleine Methode zusammengefrickelt die diese Aufgabe bewältigen soll - das tut sie auch, nur wie sie das tut gefällt mir nicht so recht. So weiß ich auch nicht wie fehleranfällig bzw zuverlässig sie ist. Und das sollte sie, weil sie in einem firmeninternen Netzwerk ständig eingesetzt werden wird!
Hier ist sie:


function sortMultiArray(arr, attr) {  
  var tmp = new Array();
  for (var i=0; i<arr.length; i++) {
    if (empty(arr**[0])) break; //Überprüft ob Array leer ist
    tmp** = arr**[attr]+";"+i;
  }
  tmp.sort();
  var tmp2 = multi_array(tmp.length);
  for (var i=0; i<tmp2.length; i++) {
    var index = parseInt(tmp**.replace(/(\w*);(\S*)/, '$2'));
    for (x in arr**) {
      tmp2**[x] = (isset(arr[index])) ? arr[index][x] : "null";
    }
  }
  return tmp2;
}

function multi_array(laenge) {
    var a = new Array();
    for (var i=0; i<laenge; i++) {
        a** = new Array();
    }
    return a;
}

function isset(obj) {
    if (typeof(obj)=="undefined") {
        return false;
    } else {
        return true;
    }
}

function empty(a) {
    if (a=="" || a==false || a==null || typeof(a)=="undefined") {
        return true;
    } else {
        return false;
    }
}

Hat jemand eine Idee wie man das mit weniger Schlamperei lösen könnte?

Zur funktionsweise meines Codes:
sortMultiArray(, )
multi_array(<größe des arrays>) --> erstellt ein mehrdimensionales Array
isset(); empty() --> haben eigentlich ziemlich die gleiche funktion - überprüfen ob ein wert oder ein objekt leer oder undefiniert ist

in der sortMultiArray()
werden zuerst die werte nach denen sortiert werden soll in ein array gepackt - mit ihrem index den sie im übergebenen array haben, hinten dran.
Dieses neue Array wird dann mittels sort() sortiert.
Dann wird ein neues muli_array angelegt. Mit einer for-schleife wird jetzt das vorhin erzeugte array durchlaufen. es fällt mir schwer hier den ablauf richtig zu beschreiben. mit replace() wird mittels einer regular-expression der zuvor angefügte index vom string aus dem vorherigen array getrennt.

Habe endlich eine zuverlässige Lösung gefunden! :smiley:
(Die obige unterschlägt sogar öfters Datensätze, ist mir aufgefallen)

function sortMultiArray(arr, attr, sort) {  
  //Initialisierung von neuem MultiArray
  var tmp = multi_array(arr.length);
  //Array für Filterwerte
  var test = new Array();
  //Filterwerte in Array:test schreiben
  for (var i=0; i<arr.length; i++) {
    test** = arr**[attr];
  }
  
  //Array:test sortieren
  test.sort();
  if (!sort) test.reverse(); //wenn sort=false, rückwärts sortieren
  //Array mit Filterwerten durchlaufen lassen
  for (var i=0; i<test.length; i++) {
    //Original-MultiArray
    for (var i2=0; i2<arr.length; i2++) {
      //Überprüft ob Filterwert gleich Attributwert
      if (test**==arr[i2][attr]) {
        //Werte aus arr[i2] in tmp** schreiben
        for (x in arr[i2]) {
          tmp**[x] = arr[i2][x];
        }
        //Filterwert aus Array:test löschen
        test** = null;
        arr[i2][attr] = null;
        break;
      }
    }
  }
  return tmp;
}

Aufruf:
sortMultiArray(String[][] , String/Int , Boolean <true=normal sortiert / false=rückwärts sortiert>)
Wichtig - das Array darf keine undefinierten Stellen enthalten (leerer String ist erlaubt), ansonsten wird nichts zurückgeliefert!

Hi,

Folgende Lösung ist wesentlich eleganter:


<html>
<head>
<title>Test</title>
</head>
<body>
<script type="text/javascript">
attr = 0; //"Sortier-Index" (global)
test();
function test(){
  iMAX = 42,       //1.ter Max-Index 
  jMAX = 10;       //2.ter Max-Index 
      
  //Zweidimensionales Array erzeugen:
  var my2DArr = new Array(iMAX);
  for (var i = 0; i < my2DArr.length; ++i){
    my2DArr** = new Array(jMAX);
  }
  //2D Array mit Werten füllen:
  for (var i = 0; i < iMAX; ++i){
    for (var j = 0; j < jMAX; ++j){
      my2DArr**[j] = Math.round(Math.random()*100);
    }
  }
  //2D Array sortieren:
  my2DArr.sort(cmp2DArrAttr);
  //2D Array ausgeben:
  for (var i = 0; i < iMAX; ++i){
    for (var j = 0; j < jMAX; ++j){
    document.write((my2DArr**).join(", "));
    document.write("</br>");
    }
  }
}
//Vergleichsfunktion für sort:
function cmp2DArrAttr (a, b) {
  return (a)[attr] - (b)[attr];
}
</script>
</body>
</html>

Man kann also die herkömmliche sort-Methode auf das
2D-Array anwenden. Mann muss ihr nur die winzig kleine
Vergleichsfunktion am ende des script-Tags übergeben :slight_smile:
Über diese Funktion vergleicht die sort Funktion dann ein Attribut
des 2D-Arrays, dass ganz am Anfang global definiert wird.

Ohne Beispiel ist der effektive JavaScript-Code auf folgende
Zeilen geschrumpft:


attr = 0; 
function cmp2DArrAttr (a, b) {
  return (a)[attr] - (b)[attr];
}

Wenn du bei deinem Code-Snippet die for-in Schleife
weglässt und stattdessen eine for-Schleife nimmst,
die bis i<(my2DArray**).length zählst sollte
es nicht mehr notwendig sein auf leere Arrays zu prüfen.
Dann werden nämlich wirklich alle Elemente durchlaufen.

P.S: Ein JavaScript Code Block für das Forum wäre schön.
Dann könnte man den Code besser lesen und vielleicht
sogar kopieren, ohne dass die Formatierung futsch ist. :wink:

Gibt es man muss nur

 schreiben

Hi Folks!
Ich hab’ mir da auch mal was gestrickt :

[Javascript][/Javascript]

Aber warum so kompliziert ? So geht’s wunderbar :stuck_out_tongue_winking_eye: