Avatar billede jps2mt Nybegynder
11. februar 2003 - 22:00 Der er 25 kommentarer og
2 løsninger

Sortere et array

Jeg har et array, som dimmes på flg. måde

Public Type IPnummer
IP As String
Antal As Integer
End Type

Global Source() As IPnummer


Herefter har jeg brug for at sortere arrayet stigende efter Antal

Kan det lade sig gøre på en eller anden smart måde, og er der evt. en der gider demonstrere??

Synes ikke jeg kan finde noget i Visual Basic der svarer til PHP's funktion sort()
Avatar billede bernhof Nybegynder
11. februar 2003 - 22:07 #1
Følgende sub sorterer en array. For at sortere skriver du bare:
SortArray Source

Sub SortArray(ArrayName)
    If Not IsArray(ArrayName) Then Exit Sub

    Limit = UBound(ArrayName)
    Do
        iSwitch = False
        For row = 0 To (Limit - 1)
            If ArrayName(row) > ArrayName(row + 1) Then
                strCopy = ArrayName(row)
                ArrayName(row) = ArrayName(row + 1)
                ArrayName(row + 1) = strCopy

                iSwitch = row
            End If
        Next

        Limit = iSwitch
    Loop While iSwitch
End Sub
Avatar billede jps2mt Nybegynder
11. februar 2003 - 22:15 #2
Hmmm...Det virker desværre ikke...

Compile error:

Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions
Avatar billede bernhof Nybegynder
11. februar 2003 - 22:22 #3
Det er fordi du skal lægge dette:

Public Type IPnummer
IP As String
Antal As Integer
End Type

.. over i et public Modul..
Avatar billede jps2mt Nybegynder
11. februar 2003 - 22:33 #4
Det er det allerede...
Avatar billede bernhof Nybegynder
11. februar 2003 - 22:38 #5
Hmm .. Det er nok et problem at sortere Types .. Det kan jeg desværre ikke hjælpe dig med.
Avatar billede martin_moth Mester
12. februar 2003 - 12:40 #6
Hmm - jeg synes jeg kan genkende

Public Type IPnummer
  IP As String
  Antal As Integer
End Type

eftersom jeg selv har skrevet det i www.eksperten.dk/spm/314370 ;o)

Det er jo bare at ændre ganske lidt i svaret fra mikbj, der jo opererer med et array af almindelige typer. Hvis du vil sorterer efter IP skriver du naturligvis

  ArrayName(row).IP i stedet for ArrayName(row)
Avatar billede martin_moth Mester
12. februar 2003 - 12:43 #7
Ovenstående fremgår i øvrigt ganske tydeligt i det spørgsmål hvor jeg introducerer den brugerdefinerede type for dig:

For at tilgå IP skriver du MitArray(index).IP
For at tilgå Antal skriver du MitArray(index).Antal

De der ti års erfaring er vist ikke fra VB (sorry - kunne ikke lade være ;o)
Avatar billede jps2mt Nybegynder
12. februar 2003 - 17:52 #8
Synes ikke rigtigt det fremgår der hvordan man kan sortere arrayet, men okay...Prøver da bare dit eks...

Og de 10 års erfaring er med VB, Pascal, Basic, ASP og PHP :)
Avatar billede jps2mt Nybegynder
12. februar 2003 - 17:56 #9
Men ak nej...Det virker ikke... :)
Stadig samme fejl...
Avatar billede martin_moth Mester
12. februar 2003 - 19:20 #10
Ja, det var kun den ene af 2 fejl jeg fandt. Den anden er, at du ikke må sende et array af brugerdefinerede typer som parameter. Men da du jo netop har erklæret Source() som en GLOBAL variabel, er det jo også ren nonsens at sende det med som en parameter til en Sub. Ret Sub'en fra mikbj så den IKKE modtager noget i procedurehovedet, men i stedet opererer direkte på Source.
Og tilføj den rettelse jeg har givet med at bruge ArrayName(row).Antal i stedet for ArrayName(row)

Det virker - har nemlig selv prøvet efter denne gang ;o)
Avatar billede bernhof Nybegynder
12. februar 2003 - 19:25 #11
Tja, således:

Sub SortSource()
    Limit = UBound(sSource)
    Do
        iSwitch = False
        For row = 0 To (Limit - 1)
            If sSource(row).Antal > sSource(row + 1).Antal Then
                strCopy = sSource(row).Antal
                sSource(row).Antal = sSource(row + 1).Antal
                sSource(row + 1).Antal = strCopy

                iSwitch = row
            End If
        Next

        Limit = iSwitch
    Loop While iSwitch
End Sub
Avatar billede jps2mt Nybegynder
12. februar 2003 - 19:40 #12
Hmmm...Det lyder interessant...Det kan jo med en lille smule omskrivning også tage destination() og port() med... :)

Kigger lige på det efter jeg har været inde og se Min Søsters Børn I Sneen... :)
Avatar billede jps2mt Nybegynder
12. februar 2003 - 22:38 #13
Og det har så lige vist sig at være NÆSTEN brugbart...

Kan bare ikke lige se hvorfor den skipper en IP hver gang...

Og så har jeg desuden måttet omskrive den til flg:

Sub SortArrays()
Limit = UBound(Source)
Do
  iSwitch = False
  For Row = 0 To (Limit - 1)
  If Source(Row).Antal < Source(Row + 1).Antal Then
    strCopy = Source(Row).Antal
    Source(Row).Antal = Source(Row + 1).Antal
    Source(Row + 1).Antal = strCopy

    strCopy = Source(Row).IP
    Source(Row).IP = Source(Row + 1).IP
    Source(Row + 1).IP = strCopy

    iSwitch = Row
  End If
  Next

  Limit = iSwitch
Loop While iSwitch
End Sub

Da alene sortering på .Antal kun sorterer antal, dvs. IP'en bliver ikke sorteret med... :)

Og som i nok vil bemærke har jeg ændret det til faldende, som var det jeg egentligt mente, men fik åbenbart skrevet stigende... :)
Avatar billede martin_moth Mester
12. februar 2003 - 23:20 #14
Hvad mener du med at den ikke "sorterer IP'en med"?

Hvis det er således, at når du flytter fx. MitArray(index).Antal og den tilsvarende MitArray(index).IP ikke flytter med (gør den virkelig ikke det - ja, jeg har aldrig prøvet det, men det lyder da mystisk. Whatever - ikke alting opfører sig som man forventer;-), ja så er det jo bare at flytte både .Antal OG(!!!) .Ip i din Sub SortArrays()

Lige nu flytter den kun .Antal

Det er blot at kopiere et par linier og skifte .Antal til .IP

/Martin
Avatar billede bernhof Nybegynder
13. februar 2003 - 16:05 #15
Ja .. prøv denne:

Sub SortSource()
    Dim intAntal As Integer, strIP As String, row As Long, Limit As Long, iSwitch
   
    Limit = UBound(Source)
    Do
        iSwitch = False
        For row = 0 To (Limit - 1)
            If Source(row).Antal < Source(row + 1).Antal Then
                strIP = Source(row).IP
                intAntal = Source(row).Antal
                Source(row).Antal = Source(row + 1).Antal
                Source(row).IP = Source(row + 1).IP
                Source(row + 1).IP = strIP
                Source(row + 1).Antal = intAntal
               
                iSwitch = row
            End If
        Next

        Limit = iSwitch
    Loop While iSwitch
End Sub
Avatar billede jps2mt Nybegynder
13. februar 2003 - 19:27 #16
Jeg havde lavet en lille stave fehler...Jeg havde fået den til at sortere IP'en med...Mit problem var at den dumpede en IP hver gang....Altså "glemmer" en IP...

Inden jeg sorterer har jeg f.eks. en UBound på 3 men efter er den så kun på 2...
Avatar billede martin_moth Mester
13. februar 2003 - 21:12 #17
Så har du lavet en fejl i din kode. Se mit og mikbj's svar ovenfor
Avatar billede jps2mt Nybegynder
13. februar 2003 - 21:55 #18
martin_moth >> Kan ikke se at det løser mit problem med at den glemmer en IP...Det er jo stort set samme kode som jeg selv havde fået lavet, bare skrevet på en anden måde...
Avatar billede jps2mt Nybegynder
13. februar 2003 - 22:12 #19
Hmmm...Kom til at se lidt nærmere efter...UBound er stadig 3 som i eks. men den sidste i arrayet er blank...Dvs. IP = "" og Antal = 0...
Avatar billede martin_moth Mester
13. februar 2003 - 22:52 #20
1) Så var IP også "" før du kørte sorteringen
2) Der er en fejl i din sorteringsalgoritme.

Løsningen ligger i en eller 2

For at undgå slåfejl (kunne være forklaringen på 2), hvor du taster et forkert variabelnavn ind (der naturligvis indeholder ingenting), kan du få VB til at kræve variabelerklæring - så fanger du alle slåfejl! I øvrigt det eneste rigtige at erklære variabler - altid!
Avatar billede bernhof Nybegynder
14. februar 2003 - 02:20 #21
Og hvis du ikke kender til, som martin_moth foreslår, at få VB til at kræve variabeleklæring, gøres det ved at lægge følgende linie ..

Option Explicit

.. i toppen af dine moduler.

Mht. sorteringen - har du overhovedet prøvet den kode jeg lagde i mit seneste svar? Den virker fint for mig!
Avatar billede martin_moth Mester
14. februar 2003 - 09:44 #22
... Eller gå til Tools -> Options, under fanebladet Edit vælger du "Require Variable declaration"

Og NU kan der vist snart ikke koges mere suppe på dette spørgsmål ;o)
Avatar billede bernhof Nybegynder
14. februar 2003 - 14:10 #23
Så sandt :o)
Avatar billede jps2mt Nybegynder
14. februar 2003 - 16:16 #24
F.eks. sådan her ser arrayet ud FØR sortering:

'192.168.2.2' optræder 3 gange
'80.222.178.72' optræder 1 gange
'212.242.89.206' optræder 1 gange
'80.202.63.9' optræder 1 gange
'192.168.2.10' optræder 1 gange
'' optræder 0 gange
'65.40.185.105' optræder 1 gange
'61.174.197.54' optræder 1 gange

Og sådan her efter:

'192.168.2.2' optræder 3 gange
'80.222.178.72' optræder 1 gange
'212.242.89.206' optræder 1 gange
'80.202.63.9' optræder 1 gange
'192.168.2.10' optræder 1 gange
'65.40.185.105' optræder 1 gange
'61.174.197.54' optræder 1 gange
'' optræder 0 gange

Og det er med flg. sorterings kode:

Sub SortArrays()
Dim Limit As Integer, iSwitch, Row As Integer, strCopy As String
Limit = UBound(Source)
Do
  iSwitch = False
  For Row = 0 To (Limit - 1)
  If Source(Row).Antal < Source(Row + 1).Antal Then
    strCopy = Source(Row).Antal
    Source(Row).Antal = Source(Row + 1).Antal
    Source(Row + 1).Antal = strCopy

    strCopy = Source(Row).IP
    Source(Row).IP = Source(Row + 1).IP
    Source(Row + 1).IP = strCopy

    iSwitch = Row
  End If
  Next

  Limit = iSwitch
Loop While iSwitch
End Sub
Avatar billede jps2mt Nybegynder
14. februar 2003 - 16:19 #25
Sorry...Fejl i min copy & paste...Sådan her kunne den se ud før:

'62.87.242.196' optræder 1 gange
'192.168.2.3' optræder 11 gange
'192.168.2.2' optræder 1 gange
'61.216.32.83' optræder 1 gange

Og efter:

'62.87.242.196' optræder 1 gange
'192.168.2.2' optræder 1 gange
'61.216.32.83' optræder 1 gange
'' optræder 0 gange
Avatar billede jps2mt Nybegynder
14. februar 2003 - 16:21 #26
Hmmm...Faldt selv lige over fejlen :)

For Row = 0 To (Limit - 1)

skulle rettes til

For Row = 1 To (Limit - 1)

Så nu virker det...
Avatar billede bernhof Nybegynder
14. februar 2003 - 18:29 #27
Ok, og se så lige at få lukket det her spm.
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
Kurser inden for grundlæggende programmering

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