Smalltalk 中真的没有预定义的动态 2d 容器吗?我必须自己做吗?

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

我需要一个动态 2d 容器,令我惊讶的是我在集合中找不到任何有用的东西。所以我用 oldskool 的方式做了我自己的,但不知怎么的,我觉得我一定少了什么东西。 smalltalk pharo 中的整个概念是基于使用他们的东西而不是必须构建你自己的东西。

Pharo 有 Matrix class。这几乎是一个 2d 容器,除非你在谈论其他我不明白的东西:)

好的,所以你想要 collection 的 objects(在你的例子中是变形)按行和列排列。这是一种方法

  1. 初始化: 在你的 class 中创建一个实例变量来保存 objects,并将其初始化为:

    morphs := OrderedCollection new
    
  2. 补充: 将新的 object 放入您的 collection 通过这样的方法

    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
    

请注意,通过添加 nil 恰好 j - row size 次(可能是 <= 0)确保在行 ij 处存在一个插槽.

  1. 检索:获取网格中给定位置的object或nil

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

另一种可能性是使用 Dictionary,如果网格很大且稀疏,这可能有意义。在这种情况下,您可以执行以下操作

  1. 初始化

    morphs := Dictionary new
    
  2. 加法

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

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

请注意,我对键使用了关联 i -> j。另一种可能性是使用对 {i.j}.