Closed4
数字文字列(string)を数値(int)にしたい

きっかけ
VerseにGetSecondsSinceEpoch関数が登場し、現実の日時を扱うことができるようになった。
そこで、西暦月日を表す8文字の数字から、西暦・月・日のそれぞれint型で分けようとしたところ、string型をint型にする関数がないことを知る。
試してみること
- 数字1文字を数値(int型)にする
- 2文字以上の数字を数値(int型)にする
- 西暦月日の8文字から、西暦・月・日のそれぞれ数値(int型)に分ける

数字1文字を数値(int型)にする
(a) UTF-8を使う方法
using { /Fortnite.com/Devices }
converting_a_numeric_string_to_a_number := class(creative_device):
NumCharArr:[]char = array{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
OnBegin<override>():void=
Print("NumChar.UTF8Code[] ---------------------------------------------")
for(I -> NumChar : NumCharArr):
if(NumInt:int = NumChar.UTF8Code[]):
Print("NumCharArr[{I}]: NumChar={NumChar}, NumInt: {NumInt}")
else:
Print("NumCharArr[{I}]: NumChar={NumChar}, NumInt: Error")
# 数字1文字に対応するUTF-8コードを数値(int型)に変換する。数字ではない場合、失敗する。
(NumChar:char).UTF8Code()<transacts><decides>:int=
var RetValueOpt:?int = false
case(NumChar):
'0' => set RetValueOpt = option{0x30}
'1' => set RetValueOpt = option{0x31}
'2' => set RetValueOpt = option{0x32}
'3' => set RetValueOpt = option{0x33}
'4' => set RetValueOpt = option{0x34}
'5' => set RetValueOpt = option{0x35}
'6' => set RetValueOpt = option{0x36}
'7' => set RetValueOpt = option{0x37}
'8' => set RetValueOpt = option{0x38}
'9' => set RetValueOpt = option{0x39}
_ => Print("UTF8Code() NumChar Error. {NumChar}")
RetValueOpt?
[Output Log]
LogVerse: : NumChar.UTF8Code[] ---------------------------------------------
LogVerse: : NumCharArr[0]: NumChar=0, NumInt: 48
LogVerse: : NumCharArr[1]: NumChar=1, NumInt: 49
LogVerse: : NumCharArr[2]: NumChar=2, NumInt: 50
LogVerse: : NumCharArr[3]: NumChar=3, NumInt: 51
LogVerse: : NumCharArr[4]: NumChar=4, NumInt: 52
LogVerse: : NumCharArr[5]: NumChar=5, NumInt: 53
LogVerse: : NumCharArr[6]: NumChar=6, NumInt: 54
LogVerse: : NumCharArr[7]: NumChar=7, NumInt: 55
LogVerse: : NumCharArr[8]: NumChar=8, NumInt: 56
LogVerse: : NumCharArr[9]: NumChar=9, NumInt: 57
出力結果は10進数
(b) 数字を直接int型にする方法
using { /Fortnite.com/Devices }
converting_a_numeric_string_to_a_number := class(creative_device):
NumCharArr:[]char = array{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
OnBegin<override>():void=
Print("NumChar.ToInt[] ------------------------------------------------------------")
for(I -> NumChar : NumCharArr):
if(NumInt:int = NumChar.ToInt[]):
Print("NumCharArr[{I}]: NumChar={NumChar}, NumInt: {NumInt}")
else:
Print("NumCharArr[{I}]: NumChar={NumChar}, NumInt: Error")
# 数字1文字を数値(int型)に変換する。数字ではない場合、失敗する。
(NumChar:char).ToInt()<transacts><decides>:int=
var RetValueOpt:?int = false
case(NumChar):
'0' => set RetValueOpt = option{0}
'1' => set RetValueOpt = option{1}
'2' => set RetValueOpt = option{2}
'3' => set RetValueOpt = option{3}
'4' => set RetValueOpt = option{4}
'5' => set RetValueOpt = option{5}
'6' => set RetValueOpt = option{6}
'7' => set RetValueOpt = option{7}
'8' => set RetValueOpt = option{8}
'9' => set RetValueOpt = option{9}
_ => Print("ToInt() NumChar Error. {NumChar}")
RetValueOpt?
[Output Log]
LogVerse: : NumChar.ToInt[] ----------------------------------------------
LogVerse: : NumCharArr[0]: NumChar=0, NumInt: 0
LogVerse: : NumCharArr[1]: NumChar=1, NumInt: 1
LogVerse: : NumCharArr[2]: NumChar=2, NumInt: 2
LogVerse: : NumCharArr[3]: NumChar=3, NumInt: 3
LogVerse: : NumCharArr[4]: NumChar=4, NumInt: 4
LogVerse: : NumCharArr[5]: NumChar=5, NumInt: 5
LogVerse: : NumCharArr[6]: NumChar=6, NumInt: 6
LogVerse: : NumCharArr[7]: NumChar=7, NumInt: 7
LogVerse: : NumCharArr[8]: NumChar=8, NumInt: 8
LogVerse: : NumCharArr[9]: NumChar=9, NumInt: 9

2文字以上の数字を数値(int型)にする ✅UTF-8を使った方法
using { /Fortnite.com/Devices }
converting_a_numeric_string_to_a_number := class(creative_device):
OnBegin<override>():void=
NumTextArr:[]string = array:
"0"
"1"
"-1"
"123"
"-123"
for(I -> NumText : NumTextArr):
Print("NumText.ToInt[] ----------------------------------------------")
if(NumInt := NumText.ToInt[]):
Print("NumTextArr[{I}]: NumText={NumText}, NumInt: {NumInt}")
else:
Print("NumTextArr[{I}]: NumText={NumText}, NumInt: Error")
# 文字列を数値に変換する。文字列が不適当な場合、失敗する。
(NumText:string).ToInt()<transacts><decides>:int=
var RetValueOpt:?int = false
var IsNegative:logic = false
var Result:int = 0
for(I := 0..NumText.Length-1, Char := NumText[I]):
if(I = 0, Char = '-'):
set IsNegative = true
else:
CharCode := Char.UTF8Code[]
set Result = Result * 10 + (CharCode - 0x30)
Print("NumText={NumText}, NumText[{I}]={Char}, CharCode={CharCode}, 0x30={0x30}, Result={Result}")
if(IsNegative?):
set RetValueOpt = option{-Result}
else:
set RetValueOpt = option{Result}
RetValueOpt?
# 数字1文字に対応するUTF-8コードを数値(int型)に変換する。数字ではない場合、失敗する。
(NumChar:char).UTF8Code()<transacts><decides>:int=
var RetValueOpt:?int = false
case(NumChar):
'0' => set RetValueOpt = option{0x30}
'1' => set RetValueOpt = option{0x31}
'2' => set RetValueOpt = option{0x32}
'3' => set RetValueOpt = option{0x33}
'4' => set RetValueOpt = option{0x34}
'5' => set RetValueOpt = option{0x35}
'6' => set RetValueOpt = option{0x36}
'7' => set RetValueOpt = option{0x37}
'8' => set RetValueOpt = option{0x38}
'9' => set RetValueOpt = option{0x39}
_ => Print("UTF8Code() NumChar Error. {NumChar}")
RetValueOpt?
Verseではchar型-char型(例: '1'-'0')ができないため、ToInt()で「CharCode - 0x30」を行っている。
(参考)
[Output Log]
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=0, NumText[0]=0, CharCode=48, 0x30=48, Result=0
LogVerse: : NumTextArr[0]: NumText=0, NumInt: 0
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=1, NumText[0]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : NumTextArr[1]: NumText=1, NumInt: 1
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=-1, NumText[1]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : NumTextArr[2]: NumText=-1, NumInt: -1
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=123, NumText[0]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : NumText=123, NumText[1]=2, CharCode=50, 0x30=48, Result=12
LogVerse: : NumText=123, NumText[2]=3, CharCode=51, 0x30=48, Result=123
LogVerse: : NumTextArr[3]: NumText=123, NumInt: 123
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=-123, NumText[1]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : NumText=-123, NumText[2]=2, CharCode=50, 0x30=48, Result=12
LogVerse: : NumText=-123, NumText[3]=3, CharCode=51, 0x30=48, Result=123
LogVerse: : NumTextArr[4]: NumText=-123, NumInt: -123
✅UTF-8を使わない方法
for(I -> NumText : NumTextArr):
Print("NumText.ToInt[] ----------------------------------------------")
if(NumInt := NumText.ToInt_2[]):
Print("NumTextArr[{I}]: NumText={NumText}, NumInt: {NumInt}")
else:
Print("NumTextArr[{I}]: NumText={NumText}, NumInt: Error")
# 文字列を数値に変換する。文字列が不適当な場合、失敗する。
(NumText:string).ToInt_2()<transacts><decides>:int=
var RetValueOpt:?int = false
var IsNegative:logic = false
var Result:int = 0
for(I := 0..NumText.Length-1, Char := NumText[I]):
if(I = 0, Char = '-'):
set IsNegative = true
else:
CharNumber := Char.ToInt[]
set Result = Result * 10 + CharNumber
Print("NumText={NumText}, NumText[{I}]={Char}, CharNumber={CharNumber}, Result={Result}")
if(IsNegative?):
set RetValueOpt = option{-Result}
else:
set RetValueOpt = option{Result}
RetValueOpt?
# 数字1文字を数値(int型)に変換する。数字ではない場合、失敗する。
(NumChar:char).ToInt()<transacts><decides>:int=
var RetValueOpt:?int = false
case(NumChar):
'0' => set RetValueOpt = option{0}
'1' => set RetValueOpt = option{1}
'2' => set RetValueOpt = option{2}
'3' => set RetValueOpt = option{3}
'4' => set RetValueOpt = option{4}
'5' => set RetValueOpt = option{5}
'6' => set RetValueOpt = option{6}
'7' => set RetValueOpt = option{7}
'8' => set RetValueOpt = option{8}
'9' => set RetValueOpt = option{9}
_ => Print("ToInt() NumChar Error. {NumChar}")
RetValueOpt?
[Output Log]
結果は同じ
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=0, NumText[0]=0, CharNumber=0, Result=0
LogVerse: : NumTextArr[0]: NumText=0, NumInt: 0
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=1, NumText[0]=1, CharNumber=1, Result=1
LogVerse: : NumTextArr[1]: NumText=1, NumInt: 1
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=-1, NumText[1]=1, CharNumber=1, Result=1
LogVerse: : NumTextArr[2]: NumText=-1, NumInt: -1
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=123, NumText[0]=1, CharNumber=1, Result=1
LogVerse: : NumText=123, NumText[1]=2, CharNumber=2, Result=12
LogVerse: : NumText=123, NumText[2]=3, CharNumber=3, Result=123
LogVerse: : NumTextArr[3]: NumText=123, NumInt: 123
LogVerse: : NumText.ToInt[] ----------------------------------------------
LogVerse: : NumText=-123, NumText[1]=1, CharNumber=1, Result=1
LogVerse: : NumText=-123, NumText[2]=2, CharNumber=2, Result=12
LogVerse: : NumText=-123, NumText[3]=3, CharNumber=3, Result=123
LogVerse: : NumTextArr[4]: NumText=-123, NumInt: -123

西暦月日の8文字から、西暦・月・日のそれぞれ数値(int型)に分ける
現時点でVerseには日時を扱うクラスや構造体がない
あると今後も日時を扱いやすくなりそうなので まず作る
date_time_struct := struct:
Year:int
Month:int
Day:int
Hour:int
Minute:int
Second:int
Millisecond:int
using { /Fortnite.com/Devices }
converting_a_numeric_string_to_a_number := class(creative_device):
OnBegin<override>():void=
Test("20240907") #正常
Test("20000101") #正常
Test("2024123") #文字数が不足で失敗するケース
Test("20240907") #全角(Lengthが大きい)で失敗ケースするケース
Test(DateStr:string):void=
Print("Test({DateStr}) ----------------------------------------------")
if(DateDT:date_time_struct = DateStr.DateStringToDateTime[]):
Print("DateStr: {DateStr}, DateDT: [{DateDT.Year}/{DateDT.Month}/{DateDT.Day} {DateDT.Hour}:{DateDT.Minute}:{DateDT.Second}.{DateDT.Millisecond}]")
else:
Print("DateStr: {DateStr}, DateDT: Error")
# 西暦月日(半角8文字)をdate_time_structに変換する。文字列が不適当な場合、失敗する。
(DateStr:string).DateStringToDateTime()<transacts><decides>:date_time_struct=
var RetValueOpt:?date_time_struct = false
if(DateStr.Length = 8):
if:
YearsStr := DateStr.Slice[0, 4]
MonthsStr := DateStr.Slice[4, 6]
DaysStr := DateStr.Slice[6, 8]
then:
if:
YearsInt:int = YearsStr.ToInt[]
MonthsInt:int = MonthsStr.ToInt[]
DaysInt:int = DaysStr.ToInt[]
then:
set RetValueOpt = option:
date_time_struct:
Year := YearsInt
Month := MonthsInt
Day := DaysInt
Hour := 0 #使用しないため0を設定
Minute := 0 #使用しないため0を設定
Second := 0 #使用しないため0を設定
Millisecond := 0 #使用しないため0を設定
else:
Print("DateStringToDateTime() DateStringToInt Error. {YearsStr}, {MonthsStr}, {DaysStr}")
else:
Print("DateStringToDateTime() DateStr.Slice Error. {DateStr}")
else:
Print("DateStringToDateTime() DateStr.Length Error. {DateStr} DateStr.Length={DateStr.Length}")
RetValueOpt?
文字列を数値にする
(前回の投稿「2文字以上の数字を数値(int型)にする ✅UTF-8を使った方法」と同じ)
# 文字列を数値に変換する。文字列が不適当な場合、失敗する。
(NumText:string).ToInt()<transacts><decides>:int=
var RetValueOpt:?int = false
var IsNegative:logic = false
var Result:int = 0
for(I := 0..NumText.Length-1, Char := NumText[I]):
if(I = 0, Char = '-'):
set IsNegative = true
else:
CharCode := Char.UTF8Code[]
set Result = Result * 10 + (CharCode - 0x30)
Print("NumText={NumText}, NumText[{I}]={Char}, CharCode={CharCode}, 0x30={0x30}, Result={Result}")
if(IsNegative?):
set RetValueOpt = option{-Result}
else:
set RetValueOpt = option{Result}
RetValueOpt?
# 数字1文字に対応するUTF-8コードを数値(int型)に変換する。数字ではない場合、失敗する。
(NumChar:char).UTF8Code()<transacts><decides>:int=
var RetValueOpt:?int = false
case(NumChar):
'0' => set RetValueOpt = option{0x30}
'1' => set RetValueOpt = option{0x31}
'2' => set RetValueOpt = option{0x32}
'3' => set RetValueOpt = option{0x33}
'4' => set RetValueOpt = option{0x34}
'5' => set RetValueOpt = option{0x35}
'6' => set RetValueOpt = option{0x36}
'7' => set RetValueOpt = option{0x37}
'8' => set RetValueOpt = option{0x38}
'9' => set RetValueOpt = option{0x39}
_ => Print("UTF8Code() NumChar Error. {NumChar}")
RetValueOpt?
[Output Log]
LogVerse: : Test(20240907) ----------------------------------------------
LogVerse: : NumText=2024, NumText[0]=2, CharCode=50, 0x30=48, Result=2
LogVerse: : NumText=2024, NumText[1]=0, CharCode=48, 0x30=48, Result=20
LogVerse: : NumText=2024, NumText[2]=2, CharCode=50, 0x30=48, Result=202
LogVerse: : NumText=2024, NumText[3]=4, CharCode=52, 0x30=48, Result=2024
LogVerse: : NumText=09, NumText[0]=0, CharCode=48, 0x30=48, Result=0
LogVerse: : NumText=09, NumText[1]=9, CharCode=57, 0x30=48, Result=9
LogVerse: : NumText=07, NumText[0]=0, CharCode=48, 0x30=48, Result=0
LogVerse: : NumText=07, NumText[1]=7, CharCode=55, 0x30=48, Result=7
LogVerse: : DateStr: 20240907, DateDT: [2024/9/7 0:0:0.0]
LogVerse: : Test(20000101) ----------------------------------------------
LogVerse: : NumText=2000, NumText[0]=2, CharCode=50, 0x30=48, Result=2
LogVerse: : NumText=2000, NumText[1]=0, CharCode=48, 0x30=48, Result=20
LogVerse: : NumText=2000, NumText[2]=0, CharCode=48, 0x30=48, Result=200
LogVerse: : NumText=2000, NumText[3]=0, CharCode=48, 0x30=48, Result=2000
LogVerse: : NumText=01, NumText[0]=0, CharCode=48, 0x30=48, Result=0
LogVerse: : NumText=01, NumText[1]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : NumText=01, NumText[0]=0, CharCode=48, 0x30=48, Result=0
LogVerse: : NumText=01, NumText[1]=1, CharCode=49, 0x30=48, Result=1
LogVerse: : DateStr: 20000101, DateDT: [2000/1/1 0:0:0.0]
LogVerse: : Test(2024123) ----------------------------------------------
LogVerse: : (Rolling Back) DateStringToDateTime() DateStr.Length Error. 2024123 DateStr.Length=7
LogVerse: : DateStr: 2024123, DateDT: Error
LogVerse: : Test(20240907) ----------------------------------------------
LogVerse: : (Rolling Back) DateStringToDateTime() DateStr.Length Error. 20240907 DateStr.Length=24
LogVerse: : DateStr: 20240907, DateDT: Error
このスクラップは2024/09/07にクローズされました