使用Squeak / Smalltalk中的块对数组进行排序

时间:2016-07-31 13:33:08

标签: smalltalk squeak

我在Smalltalk中使用#sort:提出了一个我无法理解的块的问题:

ArrayedCollection » sort: aSortBlock
    "Sort this array using aSortBlock for comparing elements.
     The block should take two arguments and return true if the
    first element should preceed the second one.
    If aSortBlock is nil then <= is used for comparison."
    Self mergeSortFrom: 1
    to: self size
    by: aSortBlock 

结果如下:

| a b |
a := 10.
b := [:c :d | (c > a and: [d > a]) ifTrue: [c >= d] ifFalse: [c <= d]].
#(17 1 15 6 10 3 7 11 12 4) sort:b

有人可以一步一步详细解释吗? 首先是c = 17d = 1? 两者都不大于a(10),所以块返回c <= d
接下来发生什么?阵列实际上是如何排序的?

1 个答案:

答案 0 :(得分:3)

正如评论中所建议的那样,您可以调试#sort:方法以逐步查看它。这确实很好,我也建议你这样做。

但是,如果您先做其他两件事情,调试会更容易:(1)清楚地表达您的代码意图;(2)编写一些单元测试以确保您的代码符合意图。那么,让我们这样做!

显示您的意图:

在这种情况下,意图在分类区中被捕获:

(c&gt; a和:[d&gt; a])ifTrue:[c&gt; = d] ifFalse:[c&lt; = d]

对应于:

如果cd都高于10排序,则以升序排序

写一些测试:

您已经提供了一个示例,但我们先添加一些更简单的示例

testAllAbove10
  self assert: (#(17 11 15 12) sort: b) = #(17 15 12 11)

testAllBelow10
  self assert: (#(1 6 10 3) sort: b) = #(1 3 6 10)

testMixed
  self
    assert: (#(17 1 15 6 10 3 7 11 12 4) sort: b) = #(1 3 4 6 7 10 17 15 12 11)

您现在应该调试#sort:方法以查看它是如何工作的吗?好吧,是的,你可以在这一点上试试调试器。但是,在这种情况下,您还应该先做第三件事:从书本或在线资源中学习排序算法。一旦理论清楚,请回到测试并调试它们。通过遵循所有这些步骤,您将能够真正理解您的代码。至少,这是优秀的程序员所做的。