語境
對于我的模型,我希望有一個輸入,用戶可以在其中輸入一系列值。
例如

我想從上面顯示的輸入中得到一個包含五個數字的串列,例如[0.5 0.2 0 0.2 0.5],這樣我就可以使用他們輸入的數字進行一些計算。
問題
不幸的是,"0.5 0.2 0 0.2 0.5"如果我將型別設定為字串,那么像上面那樣設定輸入會吐出來。如果我將型別設定為數字,它將只允許輸入一個數字。
那么,我怎樣才能決議字串作為空格的基礎(即“”)?我也對替代方案持開放態度,盡管我更愿意將它保留在 Netlogo 中(例如,不讀取值的文本檔案)以使其更容易更改,因為我懷疑它會被大量使用。
我試過的
我試過使用read-from-string,但它也不喜歡上面輸入的一系列數字。我還嘗試使用explode字串擴展 ( https://github.com/NetLogo/String-Extension ) 中的函式,但我的 Netlogo (6.2.0) 版本不喜歡該擴展中的 API 并且不允許我用它。
我對 NetLogo 很陌生,如果我的問題很愚蠢或者我沒有說清楚,很抱歉!
uj5u.com熱心網友回復:
根據它的檔案,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
輸出:
observer> test
observer: [0.5 0.2 0 0.2 0.5]
observer: 0
不過,我要提醒的是,用戶很容易輸入不同格式的數字,例如0, 2, 3, 5.0,使用逗號分隔值。檢查轉換是否有效是明智的,因為您從失敗中獲得的錯誤訊息read-from-string可能對模型用戶沒有幫助。
uj5u.com熱心網友回復:
你可以組合做position,substring,read-from-string和fput。
這是作業流程:
- 創建一個回圈,只要字串包含多個數字(= 只要它包含至少一個空格,使用 進行檢查
position " " string); - 提取從第一個字符到排除的第一個空格的子字串(用 完成
substring); - 將該子字串作為數值(with
read-from-string)讀取并將其添加到list-of-numbers(withfput)中; - 洗掉字串中的第一個數字(使用
position " " string,repeat和but-first)并再次開始回圈; - 當回圈條件計算為 as
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/374420.html
上一篇:使用正則運算式替代xpath
