How to generate an ordinal number

Post

Posted
Rating:
#1 (In Topic #700)
Regular
bill-lancaster is in the usergroup ‘Regular’
Is there an available method to convert say "5" to "5th" or "23" to "23rd"?
Online now: No Back to the top

Post

Posted
Rating:
#2
Regular
bill-lancaster is in the usergroup ‘Regular’
 Since I'm looking at day values of a date,
Select Case day_number MOD 10
  Case 1
     st
  Case 2
    nd
  Case 3
    rd
  Case else
    th
End Select

I guess this will do it, a bit messy though
Online now: No Back to the top

Post

Posted
Rating:
#3
Guru
BruceSteers is in the usergroup ‘Guru’
 No, 5 is Integer, 5th is String.
It's a simple function…

Public nth(v as integer, Textonly as Boolean)
Dim s as string =iif(textonly,"",str(v))
Dim n as Integer = v ٪ 10

Select n
Case 1
S &= "st"
Case 2
S &= "nd"
Case 3
S &= "rd"
Case else
S &= "th"
Return s
End
Online now: No Back to the top

Post

Posted
Rating:
#4
Guru
BruceSteers is in the usergroup ‘Guru’
 Not so dirty…

Dim ss as string[] = ["th","st","nd","rd","th"]
Dim v as Integer = value % 10
Return Str(value) & ss[Min(v,4)]
Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Guru
cogier is in the usergroup ‘Guru’
Here is my version: -

Code (gambas)

  1. Public Sub Form_Open()
  2.  
  3.   Dim dDate As Date = Date(Now)
  4.   Dim sOrdinal As String = GetOrdinal(Format(dDate, "dd"))
  5.  
  6.   Print Format(dDate, "dddd d") & sOrdinal & Format(dDate, " mmmm yyyy")
  7.  
  8.  
  9. Public Sub GetOrdinal(sDay As String) As String
  10.  
  11.   Dim iDay As Integer = Val(sDay)
  12.   Dim sOrdinal As String = "th"
  13.  
  14.   Select Case iDay
  15.     Case 1, 21, 31
  16.       sOrdinal = "st"
  17.     Case 2, 22
  18.       sOrdinal = "nd"
  19.     Case 3, 23
  20.       sOrdinal = "rd"
  21.  
  22.   Return sOrdinal
  23.  

The result for today is Saturday 10th July 2021
Online now: No Back to the top

Post

Posted
Rating:
#6
Regular
bill-lancaster is in the usergroup ‘Regular’
I like the not so dirty solution, thanks Bruce and Cogier.
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
I like Cogier's solution very well done  ;)

I can tell you have been reading   " 'Clean  Code' by Robert C. Martin "

I think everyone should read that book
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Guru
cogier is in the usergroup ‘Guru’
I like Cogier's solution very well done ;)

I can tell you have been reading " 'Clean Code' by Robert C. Martin "

I think everyone should read that book

Thanks for the kind words, but I have never read that book!
Online now: No Back to the top

Post

Posted
Rating:
#9
Online now: No Back to the top

Post

Posted
Rating:
#10
Guru
BruceSteers is in the usergroup ‘Guru’
I like shorter, as short as can be is best for me…
I got it to a one liner <EMOJI seq="1f642" tseq="1f642">🙂</EMOJI>

Public Sub GetOrdinal(v as Integer) As String
Return(["th","st","nd","rd","th"][Min(4, v % 10)])
End

Not sure if defining a string[] ad-hoc like that works though (cant test as am at work)
<EMOJI seq="1f609" tseq="1f609">😉</EMOJI>
Online now: No Back to the top

Post

Posted
Rating:
#11
Guru
BruceSteers is in the usergroup ‘Guru’
Oops I've messed up with one problem …

The 11st <EMOJI seq="1f631" tseq="1f631">😱</EMOJI>

Dang and it was so perfect <EMOJI seq="1f923" tseq="1f923">🤣</EMOJI>,
easily fixed with an iif()

So a 2 liner..

Dim ss As String = ["th","st","nd","rd","th"]
Return(Iif(v % 100 = 11, "th", ss[Min(4, v % 10)]))

<EMOJI seq="1f60a" tseq="1f60a">😊</EMOJI>
Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
 It appears that " IIf "    is the same as  " If ",   is that correct ?

I appears that IIf is a carryover form visual basic. But seem to be the same as If in Gambas.
Online now: No Back to the top

Post

Posted
Rating:
#13
Guru
BruceSteers is in the usergroup ‘Guru’
No idea, I've always used iif.
 it exists in a few languages.

I'm rubbish with gambas <EMOJI seq="1f609" tseq="1f609">😉</EMOJI>

In the wiki iif is written before if so what's the chicken and what's the egg? , it's the same command whatever :)
/lang/iif - Gambas Documentation
<EMOJI seq="1f609" tseq="1f609">😉</EMOJI>
Online now: No Back to the top

Post

Posted
Rating:
#14
Guru
BruceSteers is in the usergroup ‘Guru’
I got home from work and was able to test and the ad-hoc string array does work :)

So my final input on this is this tested and working one liner that works on any number value..

Code (gambas)

  1. Public Sub OrdinalString(Value As Integer) As String
  2.  
  3.   Return Str(Value) & ["th", "st", "nd", "rd", "th"][If(Value % 100 = 11, 0, Min(4, Value % 10))]
  4.  
  5.  

Edit:  (not my final input lol)
oops 12 and 13 too :-\
So not a one line after all…

Code (gambas)

  1.  
  2.   Select Value % 100
  3.     Case 11, 12, 13
  4.       Return Str(Value) & "th"
  5.   Return Str(Value) & ["th", "st", "nd", "rd", "th"][Min(4, Value % 10)]
  6.  
  7.  

Also note Cogiers version is twice as fast as mine :(
Online now: No Back to the top

Post

Posted
Rating:
#15
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’

Code (gambas)

  1.   Return Str(Value) & ["th", "st", "nd", "rd", "th"][Min(4, Value % 10)]

I am still learning Gambas … I have not seen this concept till this thread.

I there anywhere that it is explained, uses and limitation ?
what is it called …. string look up ?
Online now: No Back to the top

Post

Posted
Rating:
#16
Avatar
Guru
cogier is in the usergroup ‘Guru’
I there anywhere that it is explained, uses and limitation ?
what is it called …. string look up ?

It's just an array created between the square brackets. Consider this code below, both Print lines do exactly the same thing:-

Code (gambas)

  1. Public Sub Form_Open()
  2.  
  3.   Dim iLoop As Integer
  4.   Dim sText As String[] = ["th", "st", "nd", "rd", "th"]
  5.  
  6.   For iLoop = 0 To 4
  7.     Print sText[iLoop]
  8.     Print ["th", "st", "nd", "rd", "th"][iLoop]
  9.   Next
  10.  
Online now: No Back to the top

Post

Posted
Rating:
#17
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
Thank You … That is a good explanation  so it is just indexing an array   :D  
I think I understand better now

Edit :

Another question comes to mind, is either method more efficient or faster, to assign the array to a variable or create it on the fly ?

Edit Again  :D

I decided to test it my self and creating the array is about twice as fast and the other method
I guess that is because it is only creating the array once as opposed to creating it 4 times
Online now: No Back to the top

Post

Posted
Rating:
#18
Guru
BruceSteers is in the usergroup ‘Guru’
 I have a habit of ditching as many single use variables as I can.

It's amazing the way you can use the dot . To pass all sorts of things in one line of text.

If you need to re-use the variable a lot then it makes sense to create one.

The big speed increase in cogiers ordinal method was in the use of Select.
Fewer conditions to meet I think.
Online now: No Back to the top

Post

Posted
Rating:
#19
Avatar
Enthusiast
GrayGhost is in the usergroup ‘Enthusiast’
 Bruce :

could you expain :

 It's amazing the way you can use the dot . To pass all sorts of things in one line of text.
Online now: No Back to the top

Post

Posted
Rating:
#20
Guru
BruceSteers is in the usergroup ‘Guru’

grayghost4 said

Bruce :

could you expain :

 It's amazing the way you can use the dot . To pass all sorts of things in one line of text.

Something that springs to.mind is using Image to stretch a Picture…

  PictureBox1.Picture = PictureBox1.Picture.Image.Stretch(PictureBox1.Picture.Width / times, PictureBox1.Picture.Height / times).Picture

That could be done using an Image assignment variable pointer but theres no need.
I've bunched all sorts of things up into one liners <EMOJI seq="1f642" tseq="1f642">🙂</EMOJI>
Online now: No Back to the top
1 guest and 0 members have just viewed this.