Smalltalk(Pharo)中嵌套的"if"(AKA"switch")

mob*_*eng 3 smalltalk pharo

我需要用一些值填充矩阵(存储为数组数组).对于简单的扩散问题,矩阵是雅可比矩阵,看起来像这样:

J(1,1) = 1, J(N,N)=0
Run Code Online (Sandbox Code Playgroud)

并为1<n<N:

J(n,n) = -2k/dx^2 - 2*c(n)
J(n,n-1)=J(n,n+1) = k/dx^2
Run Code Online (Sandbox Code Playgroud)

其余的矩阵条目是零.

到目前为止,我有这种怪异:

(1 to: c size) collect: [ :n |
                (1 to: c size) collect: [ :m |
                    n = 1 | (n = c size)
                        ifTrue: [ m = n ifTrue: [ 1.0 ] ifFalse: [ 0.0 ] ]
                        ifFalse: [ m = n
                            ifTrue: [ -2.0 * k / dx squared - (2.0 * (c at: n)) ]
                            ifFalse: [ m = (n-1) | (m = (n+1))
                                ifTrue: [ k / dx squared ]
                                ifFalse: [ 0.0 ] ] ]
                    ] ]
Run Code Online (Sandbox Code Playgroud)

注意嵌套的"if-statements"(Smalltalk等价物).这有效.但是,是否有更优雅的方式做同样的事情?现在看来,这是不可读的.

Lea*_*lia 6

n := c size.
Matrix
  new: n
  tabulate: [:i :j | self jacobianAtRow: i column: j]
Run Code Online (Sandbox Code Playgroud)

哪里

jacobianAtRow: i column: j
  n := c size.
  (i = 1 or: [i = n]) ifTrue: [^j = i ifTrue: [1.0] ifFalse [0.0]].
  j = i ifTrue: [^-2.0 * k / dx squared - (2.0 * (c at: i))].
  (j = (i - 1) or: [j = (i + 1)]) ifTrue: [^k / dx squared].
  ^0.0
Run Code Online (Sandbox Code Playgroud)

基本上,一般的想法是这样的:每当你找到嵌套的ifs时,将该段代码单独分解为一个方法,并将嵌套转换为类似于case的枚举,它会尽可能地返回一个值.