Das OFFIZIELLE PROFAN SUPPORT FORUM
Einsteigerfragen
PROFAN-Programmierung
Helfer & Tools
Anregungen & Vorschläge
PROFAN-NEWS
Die Regeln!
2 - PROFAN-Programmierung

 Neues Thema  |  Zur Übersicht  |  Suchen  |  Einloggen   Neuerer Beitrag  |  Älteres Thema 
 Hash-Variablen auf existierenden Key prüfen
Autor: Jens-Arne Reumschüssel (---.77.8.pool.telefonica.de)
Datum:   12.03.22 09:08

Hallo,

mir fehlt im Zusammenhang mit Hash-Variablen, jedenfalls falls ich nichts übersehen habe, eine wichtige Funktion: Herauszufinden, ob ein Key zu einer Hash-Variablen existiert. Im Moment gibt es nämlich eine Fehlermeldung, wenn man einen nicht existierenden Key verwendet. Hier ein Workaround für Hash-Variablen mit bis zu fünf Dimensionen:

 declare hash h[]
 
 PROC HashKeyExists
   parameters hash hashvar[],key1$,key2$,key3$,key4$,key5$
   declare olderrlvl%,erg%,s$
   erg%=0
   olderrlvl%=@set("ERRORLEVEL",-1)
   if %pcount=2
     s$=hashvar[key1$]
   elseif %pcount=3
     s$=hashvar[key1$,key2$]
   elseif %pcount=4
     s$=hashvar[key1$,key2$,key3$]
   elseif %pcount=5
     s$=hashvar[key1$,key2$,key3$,key4$]
   elseif %pcount=6
     s$=hashvar[key1$,key2$,key3$,key4$,key5$]
   endif
   if %error=0
     erg%=1
   endif
   @set("ERRORLEVEL",olderrlvl%)
   return erg%
 ENDPROC
 
 cls
 h["test"]="1"
 print @HashKeyExists(h[],"test")
 print @HashKeyExists(h[],"irgendwas")
 waitinput
 end
 


Gruß, Jens-Arne



Nachricht bearbeitet (12.03.22 09:16)

Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Arndt Lindner (80.150.206.---)
Datum:   13.03.22 13:22

Das Workaround versagt, wenn ein leeres Element im Hash-Array auftaucht.
Beispiel:
 declare hash h[]
  
  PROC HashKeyExists
    parameters hash hashvar[],key1$,key2$,key3$,key4$,key5$
    declare olderrlvl%,erg%,s$
    print "Parameter1",key1$
    print "Parameter2",key2$
    print "Parameter3",key3$
    erg%=0
    olderrlvl%=@set("ERRORLEVEL",-1)
    if %pcount=2
      s$=hashvar[key1$]
    elseif %pcount=3
      s$=hashvar[key1$,key2$]
    elseif %pcount=4
      s$=hashvar[key1$,key2$,key3$]
    elseif %pcount=5
      s$=hashvar[key1$,key2$,key3$,key4$]
    elseif %pcount=6
      s$=hashvar[key1$,key2$,key3$,key4$,key5$]
    endif
    if %error=0
      erg%=1
    endif
    @set("ERRORLEVEL",olderrlvl%)
    return erg%
  ENDPROC
  
  cls
  h["test",,"xx"]="1"
  print @HashKeyExists(h[],"test",,"xx")
  print @HashKeyExists(h[],"irgendwas")
  waitinput
  end
 

Das hängt möglicherweise damit zusammen, dass die Indizes bei Hash-Arrays bei einem leeren Element abgeschnitten werden. Bei der Parameterübergabe an die Prozedure werden solche Lücken aber akzeptiert. Steht an der Leerstelle ein Leerstring ("") oder eine Stringvariable funktioniert es. Es ist deshalb empfehlenswert als Indexwerte von Hash-Arrays immer Variablen zu verwenden.
Für die "if ... elseif ..." Konstruktion könnte man ein "select .. caseof ..." verwenden. Ist aber reine Geschmackssache.

Gruß
Arndt



Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Heinz Brill (---.dip0.t-ipconnect.de)
Datum:   13.03.22 13:59

Für einfache Schlüsselpaare könnte man auch so vorgehen :

 Declare hash h[]
 
  cls
  h["test1"] = "100"
  h["test2"] = "2"
  h["test3"] = "3"
 
 Case Hash1KeyExists(h[], "test1") : Print h["test1"]
 Case Hash1KeyExists(h[], "bla")   : Print h["bla"]
 Case Hash1KeyExists(h[], "test3") : Print h["test3"]
 
 PROC Hash1KeyExists
 Parameters Hash hashvar[], String key1
 Declare String key, value, Long retvar
 retvar = 0
 ForEach hashvar[], key, value
    Case key = key1 : retvar = 1
 EndFor
 Return retvar
 EndProc
 
 WaitKey
 End
 


Bei mehreren müßte man etwas basteln aufgrund der Hilfe :
Zitat:


Bei der Ausgabe mit ForEach werden die Schlüssel zu einem zusammengefasst und durch den Delimiter "|" getrennt. Dieser Delimiter kann mit Set("HashDel",D) beliebig eingestellt werden, wobei D auch aus mehreren Zeichen bestehen kann. Voreingestellt ist hier das "|".


Vielleicht mit Len() die Anzahl der Delimitter ermitteln und mit SubStr$()
den passenden rausfischen.

H.Brill
XProfan X4 + FreeProfan

Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Jens-Arne Reumschüssel (62.55.217.---)
Datum:   16.03.22 13:07

Naja, ich denke, dass das Profan-interne Heraussuchen des passenden Keys erheblich schneller geht, als wenn man die im Profan-Programm mit ForEach alle einzeln durchprobiert. Hoffe ich zumindest...

Gruß, Jens-Arne

Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Heinz Brill (---.dip0.t-ipconnect.de)
Datum:   16.03.22 17:20

Denke ich auch, zumal man selber keine Schleife braucht :

   Move("ArrToList", h[])
   Print IF(SelectString(0, -1, "test4") > -1, "Vorhanden", "Nicht vorhanden")
 


H.Brill
XProfan X4 + FreeProfan

Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Arndt Lindner (80.150.206.---)
Datum:   27.05.22 11:14

Es gibt eine einfache Lösung für das Problem. Der Ausdruck:
 (sizeof(hashvar[]) > 0) && (sizeof(hashvar[key1$+Get("HashDel")+key2$+Get("HashDel")+key3$+Get("HashDel")+key4$+Get("HashDel")+key5$]) >= 0)
 

liefert das gewünschte Resultat.
Falls nicht alle Teilschlüssel bekannt sind, müsste man „wildcard“-Zeichen einfügen können. Dazu dient die folgende Prozedur. Als „wildcard“-Zeichen wird „*“ verwendet. Alle nachfolgend beschriebenen Prozeduren setzen voraus, dass die für Hash-Arrays standardmäßig vorgegebenen Delimiter verwendet werden. Für Keys sind Groß- und Kleinbuchstaben, Ziffern, der Punkt und der Unterstrich (_) erlaubt. Man kann die Prozeduren aber leicht an abweichende Gegebenheiten anpassen.
 proc HashKeyExists
   parameters hash hashvar[]          ' Weitere Parameter müssen nicht angegeben werden, da zum Zugriff $(i) verwendet wird
   declare longint i 
   var string hs = ""
     for i,2,%pcount                  ' baut den Suchstring für match$()
       if $(i) == "*"
         hs = hs + "[~.A-Za-z0-9_]*" + "~|"
       else
         hs = hs + $(i) +"~|"
       endif
     endfor
     hs = left$(hs,len(hs)-len("~|")) + chr$(254)
     clearlist
     move("ArrtoList",hashvar[])
     i = 0
     while (i < getcount(0)) && (match$(hs,getstring$(0,i)) == "")
       inc i
     endwhile
   return i < getcount(0)
 endproc
 

Eine Prozedur, die nicht nur feststellt, ob es den Schlüssel gibt, sondern alle zutreffenden Schlüssel in einer Liste zurückliefert, ist folgende:
 proc GetHashKeys
   parameters hash hashvar[]          ' Weitere Parameter müssen nicht angegeben werden, da zum Zugriff $(i) verwendet wird
   declare longint i, string rs, key, value 
   var string hs = ""
   var string rw = ""
     for i,2,%pcount                  ' baut den Suchstring für match$()
       if $(i) == "*"
         hs = hs + "[~.A-Za-z0-9_]*" + "~|"
       else
         hs = hs + $(i) +"~|"
       endif
     endfor
     hs = left$(hs,len(hs)-len("~|"))
     foreach hashvar[], key, value
       rs = match$(hs,key)
       case rs != "" : rw = rw + key + "\n"
     endfor
   return rw
 endproc
 

An dieser Stelle war die Lösung mit foreach … endfor etwas schneller als der Umweg über die Listboxliste.
Die Anzahl der gefundenen Schlüssel erhält man mit:
 proc GetAnzHashKeys
   parameters string keylist
   var longint rw = 0
   case keylist != "" : rw = len(keylist,"\n")-1
   return rw
 endproc
 

und dem Aufruf:
 anz = GetAnzHashKeys(GetHashKeys(hashvar[],"*",key2$,"*",…))
 


Gruß
Arndt

Beitrag beantworten
 
 Re: Hash-Variablen auf existierenden Key prüfen
Autor: Jens-Arne Reumschüssel (---.78.50.pool.telefonica.de)
Datum:   01.06.22 19:42

Wow, das ist mal eine geniale Lösung! Vielen Dank dafür!!

Beitrag beantworten
 Foren-Liste  |  Baumstruktur   Neuerer Beitrag  |  Älteres Thema 


 Foren-Liste  |  Zur Registrierung 
 Benutzerlogin
 Benutzername:
 Passwort:
 Login-Daten speichern:
   
 Passwort vergessen?
E-Mail-Adresse oder Username unten eingeben. Dann wird Dir per e-Mail ein neues Passwort zugeschickt.

phorum.org