categoriesByPayees := Dictionary new.
FileStream readOnlyFileNamed: 'payees-by-categories.txt' do: [ :file |
" With #readOnlyFileNamed:do: you don't have to worry about closing the file,
it ensures that #close is sent to the file, even if you leave the block through an Exception. "
[ file atEnd ] whileFalse: [
| parts |
parts := (file nextLine findTokens: $| escapedBy: Character tab)
collect: #withBlanksCondensed.
" We collect the parts #withBlanksCondensed, so we don't have to call it repeatedly in the loop.
You can use unary selectors in place of blocks with one argument. You may look at the implementation
of Collection >> #collect: and Symbol >> #value: to find out why. I'm not sure what you really want is
#findTokens:escapedBy:, it cuts the string along | characters if they are not preceded by a tab."
parts size > 1 ifTrue: [
" We skip blank lines or categories without at least one payee. "
| category |
category := parts first.
parts allButFirstDo: [ :payee |
(categoriesByPayees
at: payee
ifAbsentPut: [ OrderedCollection new ]) add: category
" Your implementation only remembers the last category encountered for a payee.
We can collect all the categories. " ] ] ] ]
Cheers, Balázs