2017-07-06 80 views
0

我試圖列出(30)列表(30)。 我有這樣的:如果Pharo Smalltalk中的陳述(無回報)爲flatten list

#(#(a a a) nil nil #(b) #(c) #(d) nil nil nil #(e e) nil #(f f) nil #(g) 
    #(h) nil nil nil #(i i) nil nil nil #(j) nil nil nil nil nil 
    #(k) #(l l l) 

而且我希望做一個程序,輪流到這只是一個像這樣的列表:

#(a a a b c d e e f f g hi i j k l l l) 

我的代碼是這樣的:

ToList: lista 
    | retorno y z | 
    retorno := Array new: 30. 
    y := 1. 
    (1 to: lista size) 
     do: [ :i | 
      z := 0. 
      (lista at: i) isNil 
      ifFalse: 
      (1 to: (lista at: i) size do: [ :j | retorno at: (y + z) put: ((lista at: i) at: j) 
       y:= y+1. 
       z:= z +1.] 
      )]. 
     ^retorno 

我想if語句存在一些問題,因爲沒有回報。我不知道該怎麼做,因爲它的工作方式沒有y:= y+1.,但它保留了一些零空格。

請幫幫我!

+0

'flatCollect'可以在單一方法調用中處理此問題 – Alexander

+2

您應該爲變量提供更多描述性名稱,以便代碼更易於理解。我可以是outerIndex,y可以是outputIndex,j可以是innerIndex,z ......好吧,不管你對z的意圖是什麼。 – JayK

+1

除了亞歷山大的提示,如果你應該自己編寫一種flatCollect:考慮不要按索引訪問集合元素,而是直接訪問。而不是'1:列表大小:[:index | 「做些什麼」(list at:index)]'簡單地寫'list do:[:each | 「與每個人做某事]'。對於輸出,您可以使用OrderedCollection而不是Array來簡單地使用'add:'來追加元素。你也可以看看Squeak/Pharo所有藏品都能理解的信息:「收集:」。 – JayK

回答

4

有你的代碼中有兩處語法錯誤:

  1. ifTrue:ifFalse:等參數時,塊與塊在Smalltalk括在方括號,括號沒有表情。在你的情況,你應該寫

    (lista at: i) isNil 
        ifFalse: 
        [1 to: (lista at: i    "<- [ not (" 
    

    ,並密切與

     z:= z +1.] 
        ]].        "<- ]] not)]." 
    
  2. 有一個點在長行的末尾丟失:

    .... put: ((lista at: i) at: j)   "<- dot missing" 
         y:= y+1. 
         z:= z +1. 
    

修復這些後兩個問題你應該能夠運行代碼,看看它是否按預期工作(或者如果不是,則調試)。但這是另一回事......


附錄

也有可疑的東西在這裏。

在Smalltalk中,我們使用單引號分隔文字字符串('Hello world')和文字字符前的美元符號,如$a

另外,我們有字面數組,它由其他文字組成,幷包含在#()之間,如#('a' $a)

現在,在您的代碼中,您已經編寫了諸如#(a a a)之類的表達式,這些表達式不符合我們剛纔看到的格式。那麼這是什麼意思?更確切地說,Smalltalk編譯器如何解釋這個符號?答案是,它會假設你的意思是:

#(#a #a #a) 

即的Symbols數組,你不想寫那麼多#秒。因此,在您的練習中,您應該考慮是否確實需要字符#($a $a $a),字符串#('a' 'a' 'a')或符號#(#a #a #a)

其他字符串也是如此。例如,#(abc de)會被編譯爲#(#abC#de) ...

...嗯...

但是且慢。如果是這樣,那麼爲什麼#(#(a a a) nil)不會編譯爲#(#(a a a) #nil)?那麼,因爲編譯器與niltruefalse ......異常!

還要注意,在Smalltalk的一些方言編譯器將interprete #((a a a))作爲#(#(a a a))所以你不必鍵入多英鎊符號...

總結。如果您選擇在字面陣列中節省一些磅數,請保持一致並寫入#((a a a))而不是#(#(a a a))。否則completeley顯式並寫#(#(#a #a #a))

1

你可以把它寫成:

flattenArray: anArray 
    | ws | 

    ws = WriteStream on: (Array new). 
    anArray do: [:subArr| : 
        subArr notNil ifTrue: [ 
         subArr do: [ :el | ws nextPut: el ]]]. 
    ^ws contents. 

有2分總論,這是很少需要通過索引來訪問集合元素,如果你正在做它,停,並認爲,如果有更優雅的方法可用。第二個WriteStreams在您想要收集一系列結果時非常方便。