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

使用Squeak/Smalltalk中的块对数组进行排序,smalltalk,squeak,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.

我在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 
ArrayedCollection»排序:aSortBlock
“使用用于比较元素的aSortBlock对该数组进行排序。
如果
第一个元素应该在第二个元素之前。

如果aSortBlock为nil,那么按照注释中的建议,您可以调试
#sort:
方法,以查看它一步一步地工作。这确实是一个很好的实践,我也建议您这样做

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

展现你的意图:

在这种情况下,在排序块中捕获意图:


(c>a和:[d>a])如果是真的:[c>=d]如果是这样的话:[c]这是一个家庭作业问题吗?你试过在调试器中单步进行吗?了解所有变量发生了什么的最简单方法。这些变量的
a
d
命名使这看起来非常不简单(是的,这是一个词)更像是家庭作业,而不是一个实际的例子。这不是家庭作业,这是以前考试的一个样本……你能解释一下逻辑吗?只需要开头……你展示的方法使用合并排序对数组进行排序。有关该算法的详细信息,你可以在谷歌上搜索“合并排序”,或查看
mergeSortFrom:to:by:
的源代码。任何排序的工作方式都是,在过程的任何一步,它都在比较两个元素。是否是前两个(如您所建议的17和1)取决于算法。不管您传递的块是什么(分配给
b
)排序将决定给定元素对的排序方式。将为该块指定两个值,如果该块返回“true”,则第一个值将被视为“较小”。
| 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
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)