aEval und Eval [erledigt] Danke Tom

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

aEval und Eval [erledigt] Danke Tom

Beitrag von messing »

Servus, hatte folgendes Problem, Codeblock im Array. Habe mit Hilfe von Tom ( er hat mir ein paar Erklärungen gegeben ) eine Lösung gefunden.
Ich hoffe, das mit Eurer Hilfe, diese Funktion verbessert und ausgebaut wird, damit man nicht gezielt Eval(aArray[1,5,3]) angeben muß.
Mir ging es darum, mehrdim Arrays mit aEval durchzugehen, und die enthaltenen Codeblöcke zur Ausführung zu bringen.

Code: Alles auswählen

aadd(aXbp,{{||oXbp:=XbpStatic():new( drawingArea, , {16,640}, {100,24},;
      { { XBP_PP_BGCLR, GRA_CLR_DARKBLUE } } )},;
   {||oXbp:caption := "Datum"},;
   {||oXbp:clipSiblings:=.T.},;
   {||oXbp:create()}})

aadd(aXbp,{{||oXbp := XbpSLE():new( drawingArea, , {16,616}, {100,24},;
      { { XBP_PP_BGCLR, GRA_CLR_DARKBLUE } } )},;
   {||oXbp:bufferLength := 8},;
   {||oXbp:tabStop := .T.},;
   {||oXbp:dataLink := {|x| IIf( PCOUNT()==0,;
      DtoC( DISPO->DAT_ANF ), DISPO->DAT_ANF := CtoD(x) ) }},;
   {||oXbp:create():setData()},;
   {||AAdd ( aEditControls, oXbp )}})
aEval(aXbp,{|cZeile|ArrayBlockEval(czeile,oXbp,drawingarea,aEditcontrols)})

   function ArrayBlockEval(cZeile,oXbp,drawingarea,aEditcontrols)
      if valtype(cZeile)="B"
      eval(czeile)
      endif
      if valtype(czeile)="A"
         a1:=len(cZeile)
         for x = 1 to a1
            if Valtype(cZeile[x])="B"
               Eval(czeile[x])
               if Valtype(cZeile[x])="A"
                  a2:=len(czeile[x])
                  for y = 1 to a2
                     if valtype(czeile[x,y])="B"
                        Eval(czeile[x,y])
                     endif
                  next
               endif
            endif
         next
      endif
   return nil
Dies ist ein Beispiel, welches Funktioniert.
Zuletzt geändert von messing am Mo, 19. Mär 2012 10:18, insgesamt 1-mal geändert.
Gruß
Bruno
Messing
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: aEval und Eval

Beitrag von Tom »

Code: Alles auswählen

aEval(aXbp,{|a,i|aEval(a,{|x|Eval(x)})})
Herzlich,
Tom
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: aEval und Eval

Beitrag von messing »

Tom hat geschrieben:

Code: Alles auswählen

aEval(aXbp,{|a,i|aEval(a,{|x|Eval(x)})})
Na jetzt wirds lustig, :D aEval im aEval.
Astfit !!! :D Ich habs mal mit aEval(oXbp[1]) versucht, aber auf die Idee aEval in aEval zu benutzen, wär ich nicht gekommen.
Man lernt nie aus.

Jetzt noch ne Frage dazu, ist die Anzahl der Dimensionen damit egal, ob 1, 2, oder 10 Dimensionen?
Ich hab nur bis zur driiten Dimension dIe Funktion gemacht und durchgetestet.

Und auch Codeblock im Codeblock. Ich werde mich damit beschäftigen, das ist sehr Interresant.

Danke für die Unterstützung
Gruß
Bruno
Messing
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15688
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: aEval und Eval

Beitrag von brandelh »

Die Anzahl der Verschachtelungsebenen ist vom System her nahezu unbegrenzt (eventuell muss man den Stackspeicher erhöhen), wenn man es übertreibt kann man es aber kaum mehr verstehen oder beherrschen ;-)

Es ist im Prinzip sogar ganz einfach, Xbase++ hat andere Arrays als z.B. Basic.
Ein Xbase++ Array (egal wieviele Dimensionen) hat vom Aufbau immer eine Dimension :!:
Allerdings kann es in dieser einen Dimmension nicht nur einfache Daten (Numerisch, String etc.) sondern auch andere Arrays speichern.
Du kannst also ein Array immer "schicht für schicht" bearbeiten.
aEval() verarbeitet genau diese oberste Schicht. und übergibt jeweils den Inhalt (wie gesagt, das kann auch ein Array sein) als ersten Parameter und (auf Wunsch) die laufende Nummer als zweiten.

Code: Alles auswählen

a := { 5, 4, 3, 2, 1 }
aeval(a, {|uVal| qout( a ) } ) 
=> 
5 
4
3
2
1

Code: Alles auswählen

a := { 5, 4, 3, 2, 1 }
aeval(a, {|uVal,nIndex| qout( nIndex, a ) } ) 
=> 
1 5 
2 4
3 3
4 2
5 1
soweit so gut,

Code: Alles auswählen

a := { {5,"A"}, 4, 3, 2, 1 }
aeval(a, {|uVal| qout( a ) } ) 
=> 
{5,"A"} 
4
3
2
1
an der Ausgabe von {5,"A"} sieht man, dass die obere Ebene abgearbeitet wird, wenn dort nun ein Array auftaucht, könnte man z.b. mit ValType() darauf reagieren.
Ich gebe es hier einfach aus. Natürlich könnte man in einer recursiven Schleife alle so gefundenen Arrays auch mit aEval() abarbeiten
und wenn man einen codeblock findet, diesen mit eval() ausführen. Aber mit jeder Ebene wird der Code und der spätere Programmlauf schwerer zu verstehen sein :!:

Es gibt Anwendungen wo sowas Sinn macht, aber meist ist es besser die Programmlogik einfacher zu halten und z.B. Objekte mit Methoden zu benutzen um die komplexeren unteren Ebenen abzubilden.

Auch ein Zugriff wie z.B. ? a[1,2] => "A" ist tatsächlich ein geschachtelter Zugriff, was an der anderen Schreibweise besser sichtbar wird:
? a[1,2] => "A"
? a[1][2] => "A" ... das kann man auch so lesen a[1] => {5,"A"}[2] => "A"
Gruß
Hubert
Benutzeravatar
messing
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 216
Registriert: Mi, 13. Jan 2010 9:42
Wohnort: Lauterbach / Hessen

Re: aEval und Eval

Beitrag von messing »

Servus,
ich hatte nur ein Problem damit, ein Array im Array anzusprechen, ohne die [1,2] etc.
Da Aeval das ganze Array durchgeht, dachte ich, das ganze Array. Mir ist jetzt klar, das Aeval zwar das ganze Array durchgeht, aber nicht die Arrays welche sich im Array befinden, naja :D ich hab zwar die Doku gelesen, doch mit dem Durchlauf falsch interpretiert :?: .
Gruß
Bruno
Messing
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: aEval und Eval [erledigt] Danke Tom

Beitrag von Tom »

Hallo, Bruno.

Wie ich Dir schon privat schrub: aEval durchläuft das Array vom ersten bis zum letzten Element. Jedes Element kann alles mögliche sein - eine einzelne Variable (dann ist mein Beispiel gefährlich!), aber auch wieder ein Array (wie in Deinem Beispiel). Das kannst Du dann problemlos als Parameter fürs nächste aEval benutzen, und die Schachtelungstiefe ist beliebig. Arrays können multidimensional sein, was auch wieder für jede Dimension gilt. Und sie müssen nicht symmetrisch sein! Ein Array kann also als erstes Element ein weiteres Array enthalten, dann eine einzelne Variable, danach ein x-dimensionales Array - spielt keine Rolle. Du hast ein quadratisches Array verwendet, weshalb die beiden geschachtelten aEvals funktionieren dürften, aber mit zwei bis fünf Zeilen Code mehr und einer Rekursion ließe sich das auch für ein beliebig-dimensionales Array machen.

Tatsächlich wird die Indexierung in Arrays irgendwann unübersichtlich, deshalb sollte man's nicht zu weit treiben, wenn der Code noch lesbar sein soll. Aber im Prinzip ist das nur durch die Ressourcen limitiert.
Herzlich,
Tom
Antworten