2017-07-06 3 views
0

J'essaie de faire une liste (30) de listes (30). J'ai ceci:Si les déclarations (pas de retours) dans Pharo Smalltalk pour aplatir la liste

#(#(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) 

Et je veux faire un programme qui se que dans juste une liste comme ceci:

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

Mon code est le suivant:

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 

Je pense il y a quelques problèmes avec les if-statements, car il n'y a pas de retour. Je ne sais pas quoi faire, car cela fonctionne sans le y:= y+1., mais il garde des espaces nuls.

S'il vous plaît, aidez-moi!

+0

'flatCollect' peut prendre soin de cela dans un seul appel de méthode – Alexander

+2

Vous devez donner vos noms de variables plus descriptives, de sorte que le code est plus facile à comprendre. je pourrais être outerIndex, y pourrait être outputIndex, j pourrait être innerIndex, et z ... bien, peu importe votre intention pour z. – JayK

+1

En plus de l'indice d'Alexander si vous devez coder un type de flatCollect vous-même: Pensez à ne pas accéder aux éléments de collection par index, mais directement. Au lieu de '1 to: list size do: [: index | "faire quelque chose avec" (liste à: index)] 'écrire simplement' list do: [: each | "faire quelque chose avec" chacun] '. Pour la sortie, vous pouvez utiliser un OrderedCollection au lieu d'un tableau et simplement utiliser 'add:' pour ajouter des éléments. Vous pouvez également consulter le message 'rassembler:' compris par toutes les collections de Squeak/Pharo. – JayK

Répondre

4

Il y a deux erreurs de syntaxe dans votre code:

  1. Les arguments de ifTrue:, ifFalse:, etc., sont le bloc et les blocs en Smalltalk sont des expressions entre crochets au carré, pas entre parenthèses. Dans votre cas, vous devriez écrire

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

    et étroite avec

     z:= z +1.] 
        ]].        "<- ]] not)]." 
    
  2. Il y a un point manquant à la fin de la longue ligne:

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

Après la fixation de ceux-ci deux problèmes, vous devriez être en mesure d'exécuter le code pour voir si cela fonctionne comme prévu (ou déboguer si ce n'est pas.) Mais c'est une autre histoire ...


ADDENDA

Il y a aussi quelque chose de suspect ici. Dans Smalltalk, nous utilisons des guillemets simples pour délimiter les chaînes littérales ('Hello world') et le signe dollar devant les caractères littéraux, par exemple $a.

En outre, nous avons des tableaux littéraux, qui sont composés d'autres littéraux et compris entre #( et ), comme dans #('a' $a).

Maintenant, dans votre code, vous avez des expressions écrites telles que #(a a a), qui ne sont pas conformes aux formats que nous venons de voir. Qu'est-ce que cela signifie? Plus précisément, comment le compilateur Smalltalk interpréterait-il cette notation? La réponse est qu'il suppose que vous vouliez dire:

#(#a #a #a) 

à savoir, un tableau de Symbols, et que vous ne voulait pas écrire tant de # s. Ainsi, dans votre exercice, vous devriez penser si vous vouliez réellement les caractères #($a $a $a), les chaînes #('a' 'a' 'a') ou les symboles #(#a #a #a).

Il en va de même pour les autres chaînes. Par exemple, #(abc de) va obtenir compilé comme #(#abC#de) ...

... mmm ...

Mais attendez une minute. Si tel est le cas, pourquoi #(#(a a a) nil) n'est-il pas compilé en tant que #(#(a a a) #nil)? Eh bien, parce que le compilateur fait une exception avec nil, true et false ... uff!

Notez également que dans certains dialectes de Smalltalk le compilateur interprete comme #((a a a))#(#(a a a)) vous n'avez pas à taper que beaucoup de dièses ...

Résumant. Si vous choisissez d'enregistrer quelques kilos dans des tableaux littéraux, soyez cohérent et écrivez #((a a a)) plutôt que #(#(a a a)). Sinon, soyez complètement explicite et écrivez #(#(#a #a #a)).

1

Vous pouvez l'écrire comme:

flattenArray: anArray 
    | ws | 

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

Il y a 2 remarques générales, il est rarement nécessaire d'accéder à des éléments de collecte par index, si vous le faites, arrêtez-vous, et pense que s'il y a des méthodes plus élégantes disponible. Les seconds WriteStreams sont pratiques lorsque vous voulez collecter des séries de résultats.