[英]Read string in an array and convert it to array in Smalltalk
我正在嘗試閱讀一個包含單詞集的文本文件,並將它們轉換為一個集合。 我首先要做的是,每當有回車符時,我就將單詞分開以將它們分組。 我成功地將其存儲在數組中。 我想做的下一件事是讀取字符串數組的內容,並通過將單詞分成數組內部的數組來再次對單詞進行分組。 可能嗎? 希望你能幫助我。 謝謝!
我試圖循環當前集合並放置一些條件,這些條件會修剪空格並將它們放入數組內的新集合中,但它不起作用。
到目前為止,這是我所做的:
句法:
| fileName fileRead values |
fileName := 'fruitVendor.txt'.
fileRead := fileName asFilename readStream.
fileValues := OrderedCollection new.
arrValues := OrderedCollection new.
[(string := fileRead upTo: Core.Character cr) isEmpty]
whileFalse: [fileValues addLast: string].
param := fileValues asArray.
param do:
[:ea |
stream := ReadStream on: ea.
[(arrString := stream upTo: Core.Character space) isEmpty]
whileFalse: [arrValues addLast: arrString].]
這是文件的內容:
fruitVendor.txt
China Beijing Apple //cr
Hawaii Honolulu Pineapple //cr
Japan Tokyo Banana //cr
Vietnam Ho chi min Pear
輸出應為:
#(#('China' 'Beijing' 'Apple')#('Hawaii' 'Honolulu' ''Pineapple)#('Japan' 'Tokyo' 'Banana')#('Vietnam' 'Ho chi min' 'Pear'))
我想要達到的目標:
將數組內部的字符串存儲到數組本身內部的新數組中,更像是字節數組。
我采取了更多的“閑聊”方式,因為@JayK向您展示了更通用的方式(它不處理'Ho chi min'
)。
我所有的示例都使用Smalltalk/X-jv
。 我將嘗試自然地做到這一點,即如何考慮這樣的問題。
首先想到的是通過空格(一個空格Character space
)“拆分”它。 對於第二個示例,三個是這樣一個方便的選擇器,分別稱為#splitBy:
和#splitByAll:
因此,我們嘗試使用:
| readFileStream citiesCollection |
readFileStream := 'C:\t\so\smalltalk\fruitVendor_space.txt' asFilename readStream.
citiesCollection := OrderedCollection new.
readFileStream linesDo: [ :eachLine |
| cities |
cities := (eachLine splitBy: Character space) select: [ :eachCity | eachCity notEmpty ].
citiesCollection add: cities asArray
].
citiesCollection inspect
結果可能不是您期望的,因為最后一個數組是:
#('Vietnam' 'Ho' 'chi' 'min' 'Pear')
這是由於您在字符串'Ho chi min'
有一個空格。
有辦法解決嗎? 在您的方案中。 讓我們使用兩個空格而不是一個空格來分割它:
| readFileStream citiesCollection spitCollection |
readFileStream := 'C:\t\so\smalltalk\fruitVendor_space.txt' asFilename readStream.
citiesCollection := OrderedCollection new.
spitCollection := OrderedCollection new.
2 timesRepeat: [ spitCollection add: (Character space) ]. "/ adding two spaces
readFileStream linesDo: [ :eachLine |
| cities |
cities := (eachLine splitByAll: spitCollection) select: [ :eachCity | eachCity notEmpty ].
cities := cities copy collect: [ :eachCity | eachCity withoutSpaces ].
citiesCollection add: cities asArray
].
citiesCollection inspect.
現在,對於'Ho chi min'
城市字符串,我們得到了正確的結果。
#('Vietnam' 'Ho chi min' 'Pear')
綜上所述,我認為(在現實生活中)最可取的方法是通過使用諸如$;
類的拆分器在源文件中進行拆分$;
( ;
character)-類似csv
文件,但帶有;
。 (沒有人說,將來您將有兩個空格來分割它-因此您需要有一個分割器來定義字符串的結尾-這可能是csv出現的主要原因)。
源文件將是:
China; Beijing; Apple;
Hawaii; Honolulu; Pineapple;
Japan; Tokyo; Banana;
Vietnam; Ho chi min; Pear;
然后,代碼看起來類似於上面的第一個代碼:
| readFileStream citiesCollection |
readFileStream := 'C:\t\so\smalltalk\fruitVendor.txt' asFilename readStream.
citiesCollection := OrderedCollection new.
readFileStream linesDo: [ :eachLine |
| cities |
cities := (eachLine splitBy: $;) collect: [ :eachCity | eachCity withoutSpaces ].
citiesCollection add: cities asArray
].
citiesCollection inspect.
您想要將第一個集合的每個元素(字符串行)轉換為基於原始元素的另一個元素(單詞數組)。 這就是collect:
消息的目的。
arrValues := fileValues collect:
[:each | | inner |
inner := OrderedCollection new.
stream := ReadStream on: each.
[(word := stream upTo: Core.Character space) isEmpty]
whileFalse: [inner addLast: word].
inner asArray "<-- this is the answer value of this block"]
請注意,根據您的Smalltalk方言,String中可能會有某種拆分方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.