Avatar billede perh Juniormester
01. februar 2001 - 19:12 Der er 9 kommentarer og
1 løsning

Sortering

Jeg skal sortere nogle linier, der starter med datoer i formattet dd-mmm-åå
f.eks 01-maj-01

Desværre sorteres der sådan at xx-jun-01 lægger sig ind under xx-maj-01
Det skulle gerne sorteres så alle maj kommer før alle jun osv.

Jeg har prøvet replace før sorteringen, således at der står 010501 og 030601, men det giver samme resultat.

Hvordan kan jeg sortere månedsvis i dato-orden?

Jeg har nu:

    fulllist = document.cookie.substring(countbegin, countend);

sublist1 = fulllist.replace(/-maj-/g,\"05\");
sublist2 = sublist1.replace(/-jun-/g,\"06\");
osv..
templist = sublist2.split(\"[\");
sortlist = templist.sort();
joinlist = sortlist.join(\"[\");
.. replace tilbage til bogstavsmåneder...
fulllist = joinlist;
Avatar billede jespernaur Nybegynder
01. februar 2001 - 20:48 #1
Du kan kalde sort med en sammenlignings-funktion som parameter, funktionen foretager
sammenligningen mellem 2 linier. Dermed har du selv fuld kontrol over rækkefølgen.

function compar( a, b )
{
  // a og b er 2 linier
  // returner -1 hvis a skal komme \'før\' b
  // returner 0 hvis a er lig b
  // returner 1 hvis a skal komme \'efter\' b
}

...

sortlist = templist.sort( compar );

Mvh
Jesper Naur
Avatar billede perh Juniormester
01. februar 2001 - 21:12 #2
Undskyld jeg afviste det, men jeg har et lille problem endnu med det. Kan jeg få det løst også?

Jeg bruger så denne:

function compar(a,b) { return a - b; }

Men det duer kun med tal, og min streng starter efter replace godt nok med et sekscifret tal, men så kommer der en tekststreng, og så kan det ikke sorteres.

Hvad kan jeg gøre ved det?


Avatar billede perh Juniormester
01. februar 2001 - 21:16 #3
Er der evt en der kan tilrette dette til at virke med mit eksempel. Problemet for mig er at få puttet mit array ind i.st.f SetObjekt:

Sorting Arrays and Object Arrays - for all browsers
To correctly sort object arrays, will require converting the value of each object to a string before comparing it with another object. Displaying an object will also require converting the value of each object to a string.

As we cannot rely on the prototype method of adapting the toString method, we will have to manually convert the value of the object each and every time it is sorted and displayed. It would also require an specific version of the sort and display functions for each and every type of user defined object.

This could be a bit time consuming, so we\'ll cheat. When we create each object we\'ll generate a new property, called value, which will hold the string value of the rest of the object.

When we come to sort or display the object, we\'ll use the value property. However, you must be aware that if you amend one of the objects other properties, then the value property will also need to be amended, or it\'ll not be a true reflection on the objects string value.

Although its possible to include an extra value property to object arrays, it is not possible to add it to normal arrays, unless you make them object arrays too, therefore we\'ll need two versions of the sort and display functions, one for normal arrays and another for object arrays:

function makeArray() {
    for (i = 0; i<makeArray.arguments.length; i++)
        this[i] = makeArray.arguments[i];
}

function padout(number) { return (number < 10) ? \'0\' + number : number; }
function y2k(number)    { return (number < 1000) ? number + 1900 : number; }

function ownObject(day,month,year,text) {
    this.value = \'\' + y2k(year) + \'/\' + padout(month) + \'/\' + padout(day) + \' \' + text;
    this.day = day;
    this.month = month;
    this.year = year;
    this.text = text;
}

function setObject(day,month,year,text) {
    myObjectArray[objectArrayIndex++] = new ownObject(day,month,year,text);
}

var objectArrayIndex = 0;
var myObjectArray = new Array();

setObject(4,11,97,\"abc\");
setObject(3,10,1996,\"123\");
setObject(2,9,1995,\"122\");
setObject(1,12,1998,\"124\");

function showArray(text,object,length) {
    document.write(text + \': \');
    for (var i=0; i<length; i++)
        document.write(object[i]+\' \');
    document.write(\'<BR>\');
}

function myBubbleSort(arrayName,length) {
    for (var i=0; i<(length-1); i++)
        for (var j=i+1; j<length; j++)
            if (arrayName[j] < arrayName[i]) {
                var dummy = arrayName[i];
                arrayName[i] = arrayName[j];
                arrayName[j] = dummy;
            }
}

function showObjectArray(text,object,length) {
    document.write(text + \': \');
    for (var i=0; i<length; i++)
        document.write(object[i].value+\' \');
    document.write(\'<BR>\');
}

function myObjectBubbleSort(arrayName,length) {
    for (var i=0; i<(length-1); i++)
        for (var j=i+1; j<length; j++)
            if (arrayName[j].value < arrayName[i].value) {
                var dummy = arrayName[i];
                arrayName[i] = arrayName[j];
                arrayName[j] = dummy;
            }
}

showObjectArray(\'Unsorted\',myObjectArray,objectArrayIndex);
myObjectBubbleSort(myObjectArray,objectArrayIndex);
showObjectArray(\'Sorted\',myObjectArray,objectArrayIndex);

var myArray = new makeArray(\"one\",\"two\",\"three\",\"four\");
var myArrayLength = 4;
showArray(\'Unsorted\',myArray,myArrayLength);
myBubbleSort(myArray,myArrayLength);
showArray(\'Sorted\',myArray,myArrayLength);

var myArray = new makeArray(333,5,44,2222,11111);
var myArrayLength = 5;
showArray(\'Unsorted\',myArray,myArrayLength);
myBubbleSort(myArray,myArrayLength);
showArray(\'Sorted\',myArray,myArrayLength);




Which run produces the following:

Unsorted: 1997/11/04 abc 1996/10/03 123 1995/09/02 122 1998/12/01 124
Sorted: 1995/09/02 122 1996/10/03 123 1997/11/04 abc 1998/12/01 124
Unsorted: one two three four
Sorted: four one three two
Unsorted: 333 5 44 2222 11111
Sorted: 5 44 333 2222 11111
Avatar billede jespernaur Nybegynder
01. februar 2001 - 21:52 #4
Du er nødt til at bruge en noget smartere sammenligning end bare
\'a - b\'. Det vil faktisk ikke engang virke at ekstrahere de første
6 tegn og lave dem om til et tal, da de er i formatet ddmmyy, hvor
datoen er i den mest betydende position, dette vil fx betyde at 310100
(31. januar 2000) vil komme efter 301201 (30. december 2001), og det
var nok ikke meningen, går jeg ud fra.

Prøv noget i retning af

function swap( line )
{
  return line.substring(4,6) +
          line.substring(2,4) +
          line.substring(0,2);
}

function compar( a, b )
{
  return swap(a) - swap(b);
}

Jeg har tilladt mig at nøjes med at svare på det oprindelige spm.

Mvh
Jesper Naur
Avatar billede perh Juniormester
01. februar 2001 - 23:30 #5
Tak skal du have.
Det fungerer lige præcis som jeg gerne ville have det.

Nu skal jeg så bare have ført datoformatet tilbage til dd-mmm-åå efter sorteringen.
Kan jewg lave en replce på substring, eller bruge swap igen? Og i så fald hvordan?
Avatar billede jespernaur Nybegynder
02. februar 2001 - 00:14 #6
Du strammer den en anelse med tillægsspørgsmål! Jeg giver dig
trods alt et par ideer:

Når sorteringen er færdig, skal du have oversat månedsnumrene
tilbage til månedsnavne. Dette sker nemmest med en tabel over månedsnavne,
således at du direkte kan slå navnet op med månedsnummeret som index.

Fx:

var monthnames = new Array( \"-måned0-\", \"-jan-\", \"-feb-\" ..... ,\"-dec-\" );

Du kan nu fremstille hver færdig linie ved

completedline = templine.substring(0,2) +
                monthnames[templine.substring(2,4)] +
                templine.substring(4);

Mvh
Jesper Naur
Avatar billede perh Juniormester
02. februar 2001 - 00:30 #7
Ja, undskyld, men det hører ligesom sammen.

Jeg har oprettet et spørgsmål med dine ekstra point.

Det er en fin løsning du har givet.
Avatar billede perh Juniormester
03. februar 2001 - 22:14 #8
Jeg vover lige en opfølgning med løfte om 60 point for et acc. svar:

Jeg ved desværre endnu ikke nok om js til at kunne få den sidste konvertering fra månedstal til månedsnavne sat ind så det virker.

Jeg har forsøgt forskelligt. Måske kan jeg bruge en mere klodset version med replace substring?
(men helst den med monthnames.

Jeg får desuden en gang imellem fejlen \" Et tal var ventet\" med henvisning til linien

sortlist = templist.sort(compar);

Kan jeg sikre at det compar tester på opfattes som talstrenge?

Dette er hvad jeg har nu:

function swap(line)
{
return line.substring(4,6) + line.substring(2,4) + line.substring(0,2);
}
function compar(a,b)
{
return eval(swap(a) - swap(b));
}

function showItems() {

    index = document.cookie.indexOf(\"TheBasket\");
    countbegin = (document.cookie.indexOf(\"=\", index) + 1);
    countend = document.cookie.indexOf(\";\", index);
    if (countend == -1) {
        countend = document.cookie.length;
    }
    fulllist = document.cookie.substring(countbegin, countend);

sublist0 = fulllist.replace(/-apr-/g,\"04\");
sublist1 = sublist0.replace(/-maj-/g,\"05\");
sublist2 = sublist1.replace(/-jun-/g,\"06\");
sublist3 = sublist2.replace(/-jul-/g,\"07\");
sublist4 = sublist3.replace(/-aug-/g,\"08\");
sublist5 = sublist4.replace(/-sep-/g,\"09\");
sublist6 = sublist5.replace(/-okt-/g,\"10\");

templist = sublist6.split(\"[\");
sortlist = templist.sort(compar);

joinlist = sortlist.join(\"[\");

fulllist = joinlist;

Herefter kommer udskrivning og det fungerer.

Det ser sådan ud i øjeblikket
Avatar billede jespernaur Nybegynder
04. februar 2001 - 00:09 #9
Så vidt jeg kan se, forventer koden en cookie med udseendet:

...TheBasket=dd-mmm-yyxxxxx[dd-mmm-yyxxxxx[dd-mmm-yyxxxx;...

Historien (som jeg kender den) melder ikke noget om, hvordan denne er blevet
opbygget. En forkert struktureret cookie vil få koden til at fejle.

Koden som den står, mangler replace af månederne jan, feb,
mar, nov, dec. Kan dette være forklaringen på fejlen \"Et tal var ventet\"?

Det har ingen mening at bruge \"eval\" i compar, da \"eval\" er beregnet til
at få udført en stump JavaScript kode, som programmet selv har opbygget dynamisk,
og det er der ikke tale om her (det skader ikke, men gør dog heller ingen gavn).

Under forudsætning af, at du kan få udryddet fejlen (som enten skyldes,
at cookie\'n er forkert opbygget af andre dele af programmet, eller at
der mangler 5 måneder i følgen af \'replace\') kan månedsnavnene genskabes
umiddelbart efter sorteringen (før \'join\') med:

for (var i = 0; i < sortlist.length; i++) {
    sortlist[i] = sortlist[i].substring(0,2) +
                  monthnames[sortlist[i].substring(2,4)] +
                  sortlist[i].substring(4);
}

Du kan iøvrigt her se, at man sagtens kan have den samme liste
på hver side af \'=\'. Det er altså unødvendigt med de mange sublist0, sublist1
etc.

Der er lige lidt tilsætning:

var _console = null;

function debug(msg)
{
  // Open a window the first time we are called, or after an existing
  // console window has been closed.
  if ((_console == null) || (_console.closed)) {
      _console = window.open(\"\", \"console\", \"width=600,height=300,resizable,scrollbars\");
      // Open a document in the window to display plain text.
      _console.document.open(\"text/plain\");
  }
  _console.document.writeln(msg);
}

Med ovennævnte funktion kan du til enhver tid i dit program skrive

debug(\"hvilkårlig tekst\");

hvilket vil åbne et separat vindue med den angivne tekst. Det er uvurderligt
til testudskrifter.

Mvh
Jesper Naur
Avatar billede perh Juniormester
21. februar 2001 - 17:29 #10
Jeg er sikker på at cookien er korrekt nu, men jeg har ikke kunnet få den baglæns konvertering tilbage til månedsnavne til at fungere. Men jeg prøver måske på et senere tidspunkt.
Imidlertid har jeg besluttet at det kan gå med månedstal efter sorteringen.

Jeg synes dog du skal have dine point, så jeg opretter et spgm med dem.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester