arrays - 读取数组中的字符串并将其转换为 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'))
我想要达到的目标:
将数组内部的字符串存储到数组本身内部的一个新数组中,更像是一个字节数组。
解决方案
我冒昧地以更“smalltalk”的方式进行操作,因为@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
结果可能不是你所期望的,因为最后一个 Array 是:
#('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')
话虽如此,我认为最可取的方式(在现实生活中)是通过使用某种拆分器(例如$;
(;
字符)-类似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.
推荐阅读
- java - 如何从数组中获取数字?
- c++ - unordered_maps 的向量,在地图中搜索太慢
- gradle - Gradle 构建失败:“您的项目路径包含非 ASCII 字符”
- r - 将第二个图例添加到 ggplot
- python - How to define a python lambda getting the first element?
- reactjs - React:如果 DOM 子级为空,则避免渲染组件的根 DOM 元素
- git - 如何更改 gi 历史记录以使提交看起来像应用在 repo 中的文件夹副本上
- bash - 列表中的随机变量值
- graphql - 如何在 GATSBY.js 中获取博客文章的“最后更新日期”
- r - 求每 3 行的平均值