Search code examples
smalltalkpharo

Is there really no predefined dynamic 2d container in Smalltalk? Do I have to make my own?


I need a dynamic 2d container and I was suprised that I could not find anything usefull in the Collections. So I made my own in oldskool fashion but somehow I feel like there must be somthing im missing. The whole concept in smalltalk pharo is based on using their stuff instead of having to build your own.


Solution

  • OK, so you want to have a collection of objects (morphs in your case) arranged by rows and columns. Here is one way to do this

    1. Initialization: Create an instance variable in your class for holding the objects, and initialize it as:

      morphs := OrderedCollection new
      
    2. Addition: Place new objects in your collection by means of a method like this one

      placeMorph: morph atRow: i column: j
        | row |
        row := morphs at: i ifAbsentPut: [OrderedCollection new].
        j - row size timesRepeat: [row add: nil].
        row at: j put: morph
      

    Note that by adding nil exactly j - row size times (which could be <= 0) ensures the existence of a slot at row i column j.

    1. Retrieval: Get the object at a given position in the grid or nil

      morphAtRow: i column: j
        | row |
        row := morphs at: i ifAbsent: [^nil].
        ^row at: j ifAbsent: [nil]
      

    Another possibility would be to use a Dictionary, which could make sense if the grid is large and sparse. In that case you could do the following

    1. Initialization

      morphs := Dictionary new
      
    2. Addition

      placeMorph: morph atRow: i column: j
        morphs at: i -> j put: morph
      
    3. Retrieval

      morphAtRow: i column: j
        ^morphs at: i -> j ifAbsent: [nil]
      

    Note that I've used associations i -> j for the keys. Another possibility would have been to use pairs {i.j}.