Search code examples
smalltalkpharosqueak

Converting Ordered Collection to Literal Array


I have an ordered collection that I would like to convert into a literal array. Below is the ordered collection and the desired result, respectively:

an OrderedCollection(1 2 3)
#(1 2 3)

What would be the most efficient way to achieve this?


Solution

  • The message asArray will create and Array from the OrderedCollection:

        anOrderedCollection asArray
    

    and this is probably what you want.

    However, given that you say that you want a literal array it might happen that you are looking for the string '#(1 2 3)' instead. In that case I would use:

        ^String streamContents: [:stream | aCollection asArray storeOn: stream]
    

    where aCollection is your OrderedCollection.

    In case you are not yet familiar with streamContents: this could be a good opportunity to learn it. What it does in this case is equivalent to:

        stream := '' writeStream.
        aCollection asArray storeOn: stream.
        ^stream contents
    

    in the sense that it captures the pattern:

        stream := '' writeStream.
        <some code here>
        ^stream contents
    

    which is fairly common in Smalltalk.

    UPDATE

    Maybe it would help if we clarify a little bit what do we mean literal arrays in Smalltalk. Consider the following two methods

    method1
      ^Array with: 1 with: 2 with: 3
    
    method2
      ^#(1 2 3)
    

    Both methods answer with the same array, the one with entries 1, 2 and 3. However, the two implementations are different. In method1 the array is created dynamically (i.e., at runtime). In method2 the array is created statically (i.e., at compile time). In fact when you accept (and therefore compile) method2 the array is created and saved into the method. In method1instead, there is no array and the result is created every time the method is invoked.

    Therefore, you would only need to create the string '#(1 2 3)' (i.e., the literal representation of the array) if you were generating Smalltalk code dynamically.