簡體   English   中英

讀取數組中的字符串,然后在Smalltalk中將其轉換為數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM