Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding collections from different instances

I am new to Smalltalk and I am trying to do a very simple program that would produce a single collection, out of multiple collections in this way:

Let's say I have a Set of Armories, and every Armory has it's own Weapons Set, what I would like to do is to write a method that would return a single collection with all the Weapons from every Armory combined.

Thanks in advance for your help!

like image 994
Guillermo Gruschka Avatar asked Dec 15 '22 03:12

Guillermo Gruschka


2 Answers

Try something like this:

armories inject: OrderedCollection new into: [:collection :armory |
   collection addAll: armory weapons; yourself].
like image 105
David Buck Avatar answered Feb 16 '23 21:02

David Buck


I'd like to improve David's answer by proposing this solution:

armories inject: OrderedCollection new into: [:allWeapons :armory |
  allWeapons, armory weapons]

As , returns concatenation of 2 collections.

Now also there is sort of more "fluid" way without creation of new OrderedCollection. There is a method called fold: or reduce: or 'reduceLeft:` which is a concept from functional programming. So you can do:

(armories collect: #weapons) fold: [allWeapons :weapons |
  allWeapons, weapons]

So armories collect: #weapons will give you a collections of collections of weapons. fold: takes 1st element and 2nd and executes the block on them. Then in take a result and a 3rd element, and so on…

Now the best solution that I know is flatCollect:. I'm sure that it's present in pharo, but may be missing from other smalltalk based languages. This is the same as collect: but flattens the result one level. So all you have to do is:

armories flatCollect: #weapons

Enjoy

like image 31
Uko Avatar answered Feb 16 '23 22:02

Uko