Ga naar inhoud
  • 0

testen op getallenreeks


Zero55

Vraag

20 antwoorden op deze vraag

Aanbevolen berichten

  • 0

Als ik de vraagsteller goed begrepen heb, gaat het er om dat dat de laatste 4 karakters allemaal een getal moeten zijn. Bij de tot nu toe genoemde oplossingen geeft bijv. "abcd12b4" een resultaat dat waar is en dat klopt dus niet.

 

Het volgende werkt wel. Daarnaast wordt er ook nog op minimaal 4 karakters getest.

 

filter ( right ( tekst ; 4 ) ; "0123456789" ) = Right ( tekst ; 4 ) and length ( tekst ) > 3

Link naar reactie
  • 0

Het lijkt erop dat je wilt checken óf je een getalreeks van 8 getallen in een veld hebt staan. In dat geval kan je (met fmpro-advanced) ook een custom-function gebruiken:

## CF_GetalReeks ( Data ; Lengte )

Let ( [ 
v = Substitute ( Data ; [ " " ; ¶ ] ) ; 
n = ValueCount ( v ) ; 
c = GetValue ( v ; 1 ) ; 
l = Length ( c ) ; 
c2 = Filter ( c ; "0123456789" ) ; 
l2 = Length ( c2 )
] ; 
Case ( l = Lengte and l2 = Lengte ; c ; n > 0 ; CF_GetalReeks ( MiddleValues ( v ; 2 ; n - 1 ) ; Lengte ) )
)

Zodra er een waarde wordt gevonden die uit een getalreeks van de opgegeven lengte verschijnt, dan exit de functie met de waarde die is gevonden. De functie geeft dan bij

CF_GetalReeks ( "Test met tekst en getallen: 01235 is te kort getal 45645647 is lang genoeg en hier nog een getal 89123645 dat niet wordt getoond" ; 8 )

45645647

als resultaat, de eerste getalreeks van 8 cijfers

Link naar reactie
  • 0

In het Case-gedeelte wordt bepaald wat er gebeurt; in dit geval wordt zodra er een waarde wordt gevonden die aan de voorwaarden voldoet, gestopt met uitvoeren. Maar dat kan je zelf naar hartelust aanpassen ... kwestie van ff goed nadenken wat je precies voor resultaat van een berekening vraagt.

Link naar reactie
  • 0

Als je de case-statement een klein beetje uitbreidt en:

Case ( l = Lengte and l2 = Lengte ; c ; n > 0 ; CF_GetalReeks ( MiddleValues ( v ; 2 ; n - 1 ) ; Lengte ) )

verandert in:

List ( If ( l = Lengte and l2 = Lengte ; c ) ; If ( n > 0 ; CF_GetalReeks ( MiddleValues ( v ; 2 ; n - 1 ) ; Lengte ) ) ) 

dus je maakt er een List() van de 2 delen van de Case() dan is de uitkomst een list van alle waarden die voldoen aan de voorwaarde van 8 cijfers lengte:

45645647
89123645

Link naar reactie
  • 0

Ik heb nog eens zitten knutselen naar aanleiding van jouw vraag hoe nu eigenlijk wordt bepaald welke waarde wordt gefilterd. Daarbij kwam ik een paar leuke issues tegen:

 

  • Je kan meer dan één reeks van een bepaalde lengte in een string hebben.
  • Een reeks van die bepaalde lengte kan opgesloten zitten in tekst, dwz kan zonder spaties ergens tussen staan
  • In die gevallen kan je de eerste willen hebben
  • Je kan de laatste willen hebben
  • Je kan ze allemaal willen hebben (een specifieke daaruit, de derde oid zou je met een GetValue() daar weer uit kunnen halen)
  • Ik wilde niet nog een extra CF maken waar je van afhankelijk zou zijn, dus ik wilde een autonome functie verzinnen

Als deze issues heb ik kunnen tackelen met de volgende functie:

CF_GetalReeks_2 ( Data ; Lengte ; Type )

Waarbij de Data en Lengte identiek zijn aan die in de vorige uitvoering van deze CF, in Type mag 0,1 of 2 worden ingevuld, waarbij:

  • 0 = de eerste geldige aaneengesloten getalreeks
  • 1 = de laatse geldige en
  • 2 = alle geldige getalreeksen

If ( Data ≠ Filter ( Data ; "0123456789 ¶" ) ; 
Let ( [ 
v1 = Data ; 
n1 = Length ( v1 ) ; 
x1 = Left ( Filter ( Left ( v1 ; 1 ) ; "0123456789 ¶" )  & " " ; 1 ) ; 
x2 = x1 & CF_GetalReeks_2 ( Middle ( v1 ; 2 ; n1 - 1 ) ; Lengte ; Type )
] ; 
If ( Data ≠ Filter ( Data ; "0123456789 ¶" ) ; x2 ; CF_GetalReeks_2 ( x2 ; Lengte ; Type ) )
) ;  
Let ( [ 
	r = Case ( Type = 1 ; 0 ; Type = 2 ; 1 ; 1 ) ; 
	v = Substitute ( Data ; [ " " ; ¶ ] ) ; 
	n = ValueCount ( v ) ; 
	c = GetValue ( v ; If ( r = 1 ; 1 ; n ) ) ; 
	l = Length ( c ) ; 
	c2 = Filter ( c ; "0123456789" ) ; 
	l2 = Length ( c2 )
] ; 
	Case ( Type = 2 ; 
		List ( If ( l = Lengte and l2 = Lengte ; c ) ; If ( n > 0 ; CF_GetalReeks_2 ( MiddleValues ( v ; 2 ; n - 1 ) ; Lengte ; Type ) ) ) ; 
		l = Lengte and l2 = Lengte ; c ; 
		n > 0 ; CF_GetalReeks_2 ( MiddleValues ( v ; 1 + r ; n - 1 ) ; Lengte ; Type ) )
)
)

De functie moet recursief worden gebruikt, omdat bij de eerste doorgang alle overbodige tekst wordt vervangen door spaties. Daarna moet het resultaat nogmaals met dezelfde functie worden bewerkt voor het juiste eindresultaat. De reden voor deze werkwijze is om getalreeksen te kunnen vinden die niet vrij in de tekst staan zoals test01234567test. Zou dit absoluut niet gebeuren, dan kan je de functie voor een deel strippen en is de recursie niet nodig. (Voor nu doe ik dus maar even moeilijk)

Het gebruik is nu bijna net zo eenvoudig als met de vorige CF, alleen moet je hem "nesten":

CF_GetalReeks_2 ( CF_GetalReeks_2 ( Data ; Lengte ; 2 ) ; Lengte ; Type )

 

Een voorbeeld is altijd handig, dus nemen we de volgende tekst:

01235 is een kort getal 45645647 is langer en hier nog een getal89123641opgesloten in wat extra tekst

En ook bij deze string willen we weer alleen een aaneengesloten getalreeks van 8 cijfers hebben.Zoals je ziet staan er twee in. De functie wordt dan als volgt gebruikt:

CF_GetalReeks_2 ( CF_GetalReeks_2 ( "01235 is een kort getal 45645647 is langer en hier nog een getal89123641opgesloten in wat extra tekst" ; 8 ; 2 ) ; 8 ; 0 )

Deze formule levert bij de eerste doorgang

01235         45645647           89123641

Dit is nu alleen maar de tekst gestript van alle niet numerieke gegevens behalve (een flink aantal) spaties en in de tweede doorgang wordt dan:

CF_GetalReeks_2 ( "01235         45645647           89123641" ; 8 ; 0 )

geëvalueerd en wordt de eerste waarde van 8 cijfers:

45645647

teruggegeven; Type 1 (laatste) geeft

89123641

en Type 2 (alles) geeft

45645647
89123641

Het valt je wellicht op dat in de binnenste aanroep voor Type = 2 (alles) is gekozen. Als je nu een string hebt die al alleen maar uit getallen en spaties zou bestaan en je zou bij type een 1 invullen en je wilt de eerste of alle waarden hebben, dan klopt je uitkomst niet, want het filterdeel van de functie wordt dan overgeslagen en dus is het handig om in de eerste doorloop altijd alle (geldige) waarden door te laten.

 

Waarom al deze moeite? Gewoon omdat het af en toe leuk is om even hard na te denken ;-)

Link naar reactie
  • 0

Kijk eens naar customList, die functie is een loop binnen een functie die intern gebruik maakt van Let en Evaluate.

 

Tot 20 000 iteraties is het gelimiteerd (maar dat zit hem enkel in de code, je kan die er ook weer uithalen)/

 

Zo kan je dan bijvoorbeeld:

Let ( 
    $list = List ( 1 ; 2 ; 3 ; 4 )
;
   CustomList ( 1 ; ValueCount ( $list ) ; "GetValue ( $list ; [n] ) + 1" )
)

En dat geeft als resultaat:

2¶3¶4¶5

 

ps: ook nog eens performanter dan de recursie methode van FileMaker :)

Link naar reactie

Doe mee aan dit gesprek

Je kunt dit nu plaatsen en later registreren. Indien je reeds een account hebt, log dan nu in om het bericht te plaatsen met je account.

Gast
Beantwoord deze vraag...

×   Geplakt als verrijkte tekst.   Plak in plaats daarvan als platte tekst

  Er zijn maximaal 75 emoji toegestaan.

×   Je link werd automatisch ingevoegd.   Tonen als normale link

×   Je vorige inhoud werd hersteld.   Leeg de tekstverwerker

×   Je kunt afbeeldingen niet direct plakken. Upload of voeg afbeeldingen vanaf een URL in

×
×
  • Nieuwe aanmaken...