1

what I want is: From integers 1 to 130, I want to print some specific integers already given in an array. They are: 2 32 44 67 89 111 123 which are stored in small-to-big order.

Here's my codes:

|a n myArray| 

myArray := #(2 32 44 67 89 111 123). 

n := 1. 
a := myArray at: n. 

1 to: 130 do: [:i| 
        i = a 
        ifTrue: [ 
                Transcript show: i; cr. 
                n := n + 1. 
                a := myArray at: n. 
                ].  
        ]. 

The output is very good except for an Error Message.

enter image description here

By my current level, I have no idea why that Error Message appears.

Q1: Why Error Message appears ?

Q2: How can I improve that?

Update:

I found another way to solve this issue:

|myArray|

myArray := #(2 32 44 67 89 111 123).

n := 1.
a := myArray at: n.

1 to: 130 do: [:i|
    i = a      
    ifTrue: [
        Transcript show: i; cr.
        n := n +1.

        n = 8
        ifTrue: [n := n - 1].


         a := myArray at: n.
        ].  
    ].

Looks ugly though.

Updated again:

|a n myArray| 

myArray := #(2 32 44 67 89 111 123). 

n := 1. 
a := myArray at: n. 

1 to: 130 do: [:i| 
        i = a 
        ifTrue: [ 
                Transcript show: i; cr. 
                n := n + 1. 

                (n = 8) ifTrue:  [^'Found it!'].

                a := myArray at: n. 
                ].  
        ].

2 Answers2

3

If you click on the debug button, you will gain access to a debugger that may help you understand what is going on.

The list in the window you are showing is the stack of execution. The snippet that you are trying to execute is marked as UndefinedObject>>DoIt. Click on it, and you'll see where your code stopped - while executing:

myArray at: n

In the debugger there are inspectors, you'll see that n = 8 if you click on n, then if you inspect myArray, you'll see that it has only 7 elements. You are thus trying to access to myArray with a subscript (an index) which is out of the Array bounds, as the error message tells...

From the debugger, you can restart the method and execute it step by step. But since it will fail at loop 123, it might be boring... You can also modify the code from within the debugger, for example use myArray := #(2 4 5). acceopt, and restart execution step by step to see if you can understand why the algorithm fails.

My suggestion is to try to think differently. You already have an Array containing the values you want to print (myArray). So if you manage to tell myArray to do what you want more directly, maybe by writing something like myArray do: [:element | ...]

aka.nice
  • 9,100
  • 1
  • 28
  • 40
3

From integers 1 to 130, I want to print some specific integers already given in an array

1 to: 130 do: [ :i | 
    (array includes: i) ifTrue: [ Transcript show: i; cr. ] ]
Uko
  • 13,134
  • 6
  • 58
  • 106
  • I think array includes: i is nice. But I guess my way is faster. Correct ? – Sleeping On a Giant's Shoulder Nov 17 '17 at 02:42
  • Yes, Uko shows O(m*n) solution, yours was O(m) but you have to make it work first. Make it work > make it fast. There are plenty other ways like `Transcript cr; show: (myArray select: [:e | e between: 1 and: 130])` – aka.nice Nov 17 '17 at 06:50