[英]How can I parse a string in Netlogo?
語境
對於我的 model,我想要一個輸入,用戶可以在其中輸入一系列值。
例如
我想從上面顯示的輸入中得到一個包含五個數字的列表,例如[0.5 0.2 0 0.2 0.5]
,因此我可以使用他們輸入的數字進行一些計算。
問題
不幸的是,如果我將類型設置為字符串,那么像上面這樣設置輸入會吐出"0.5 0.2 0 0.2 0.5"
。 如果我將類型設置為數字,它將只允許輸入一個數字。
那么,如何以空格為基礎(即“”)解析字符串? 我也對替代品持開放態度,盡管我更願意將其保留在 Netlogo 中(例如,不讀取值的文本文件)以使其更容易更改,因為我懷疑它會被很多人玩弄。
我試過的
我曾嘗試使用read-from-string
,但它也不喜歡像上面那樣輸入一系列數字。 我還嘗試使用字符串擴展名( https://github.com/NetLogo/String-Extension )中的explode
function ,但我的 Netlogo 版本(6.2.0)不喜歡來自該擴展名的 ZDB974238714CAtADE634 的 ZDB974238714CAtADE634請允許我使用它。
我對 NetLogo 很陌生,如果我的問題很愚蠢或者我沒有說清楚,很抱歉!
您可以結合position
、 substring
、 read-from-string
和fput
。
這是工作流程:
position " " string
檢查);substring
完成);read-from-string
)並將其添加到list-of-numbers
(使用fput
);position " " string
, repeat
和but-first
)並再次開始循環;FALSE
時,這意味着字符串中只剩下一個數字。 將最后一個數字(即整個剩余的字符串)添加到循環外的list-of-numbers
,這一切都完成了。 下面的過程是一個報告過程,它執行這個工作流並報告從字符串中讀取的值列表(它只需要界面中的user-string
輸入框):
to-report convert-user-string [str]
let temp-string user-string
let list-of-numbers (list)
while [position " " temp-string != FALSE] [
let next-number-as-string (substring temp-string 0 position " " temp-string)
set list-of-numbers lput (read-from-string next-number-as-string) (list-of-numbers)
repeat (position " " temp-string + 1) [
set temp-string (but-first temp-string)
]
]
set list-of-numbers lput (read-from-string temp-string) (list-of-numbers)
report list-of-numbers
end
例如:
observer> set user-string "0.5 0.2 0 0.2 0.5"
observer> show user-string
observer: "0.5 0.2 0 0.2 0.5"
observer> show convert-user-string user-string
observer: [0.5 0.2 0 0.2 0.5]
我上面發布的過程是我制作的初始代碼的精簡版,我將在下面留下大量評論:
globals [
list-of-numbers ; The list where values from the input string will be stored.
temp-string ; A temporary variable being the alter-ego of 'user-list'. This is needed because
; the 'trim-string-to-next-nonspace' procedure won't let me change the value of
; 'user-string' directly (I am not sure why, anyone please feel free to say if I'm
; missing something here) but also because you might want to keep the value of the
; user input intact - hence we use this 'temp-string' to trim the string without worries.
]
to convert-user-string [str]
; As long as there are at least two numbers in the string (identified by the presence of at least one
; space), the while loop extracts the first number with 'substring' and then assigns it as a numeric
; value to 'list-of-numbers' by using 'read-from-string' and 'lput'. At that point, it trims the
; string up to the next non-space character.
; When there is only one number left in the string (identified by the absence of spaces in the string),
; the 'more-than-one-number-in-string? temp-string'condition evaluates as 'FALSE' and the while loop
; stops. At that point, the last line of code adds what is left of the string (i.e. the last number)
; to the 'list-of-numbers' list.
set list-of-numbers (list) ; Initiating this variable as a list in order to be able to use 'lput'.
set temp-string user-string
while [more-than-one-number-in-string? temp-string] [
let next-number-as-string (substring temp-string 0 position-of-next-space temp-string)
set list-of-numbers lput (read-from-string next-number-as-string) (list-of-numbers)
trim-string-to-next-nonspace temp-string
]
set list-of-numbers lput (read-from-string temp-string) (list-of-numbers)
end
to-report more-than-one-number-in-string? [str]
; This reporter is needed as a condition for the while loop in 'convert-user-string'. The reason is that
; the 'position' command (used by the 'position-of-next-space' procedure) reports either a number (i.e.
; the position of the character in the given string) or 'FALSE' (in case the item is not present in the
; string). Therefore, this procedure is needed in order to get either TRUE or FALSE to be used in the
; while condition.
ifelse (position-of-next-space str = FALSE)
[report FALSE]
[report TRUE]
end
to-report position-of-next-space [str]
; Simply reporting the position of the next space in the string. Note that positions (indexes) in NetLogo
; are numbered starting from 0.
report position " " str
end
to trim-string-to-next-nonspace [str]
; By using 'but-first' repeatedly, this procedure gets rid of the first number (which has already been stored
; in 'list-of-numbers' by the 'convert-user-string' procedure) and the following space in the string.
; Note that the '+ 1' bit is needed because the count of positions in NetLogo starts from 0 for the first item.
let x temp-string
repeat (position-of-next-space temp-string + 1) [
set x (but-first x)
]
set temp-string x
end
根據它的文檔, read-from-string
可以解析文字值列表。 您遇到的問題是 NetLogo 列表文字必須有方括號才能打開和關閉,根據編程指南的常量列表部分。 因此,您需要做的就是將[
和]
添加到用戶的輸入中。
to test
let s "0.5 0.2 0 0.2 0.5"
let l read-from-string (word "[" s "]")
show l
show item 2 l
end
Output:
observer> test
observer: [0.5 0.2 0 0.2 0.5]
observer: 0
不過,我要提醒的是,用戶很容易輸入不同格式的數字,例如0, 2, 3, 5.0
,使用逗號分隔值。 檢查轉換是否有效是明智的,因為您從失敗的read-from-string
中獲得的錯誤消息可能對 model 用戶沒有幫助。
查看 CSV 擴展的“csv:from-string”原語。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.