I'm confused

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

I'm confused

jWarrior
Evaluating this:
| a b c |
a := OrderedCollection new.
a add: (Point x: 1 y:1).
a add: (Point x: 1 y:2).
a add: (Point x: 1 y:3).
a add: (Point x: 2 y:1).
a add: (Point x: 2 y:2).
a add: (Point x: 2 y:3).
b := a asSortedCollection: [:p1 : p2 | (p1 y < p2 y) ].
results in this: a SortedCollection(2@1 1@1 1@2 2@2 1@3 2@3)

But evaluating this:
| a b c |
a := OrderedCollection new.
a add: (Point x: 1 y:1).
a add: (Point x: 1 y:2).
a add: (Point x: 1 y:3).
a add: (Point x: 2 y:1).
a add: (Point x: 2 y:2).
a add: (Point x: 2 y:3).
b := a asSortedCollection: [:p1 : p2 | (p1 x < p2 x) and: [p1 y < p2 y]].
results in this: a SortedCollection(2@1 1@3 1@1 2@2 1@2 2@3)

I know I am overlooking something real simple, but why isn't this major
minor sort working. Thanks.


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

Ingo Blank
"Donald MacQueen" <[hidden email]> schrieb im Newsbeitrag
news:9fh9ah$94s$[hidden email]...

> Evaluating this:
> | a b c |
> a := OrderedCollection new.
> a add: (Point x: 1 y:1).
> a add: (Point x: 1 y:2).
> a add: (Point x: 1 y:3).
> a add: (Point x: 2 y:1).
> a add: (Point x: 2 y:2).
> a add: (Point x: 2 y:3).
> b := a asSortedCollection: [:p1 : p2 | (p1 y < p2 y) ].
> results in this: a SortedCollection(2@1 1@1 1@2 2@2 1@3 2@3)
>
> But evaluating this:
> | a b c |
> a := OrderedCollection new.
> a add: (Point x: 1 y:1).
> a add: (Point x: 1 y:2).
> a add: (Point x: 1 y:3).
> a add: (Point x: 2 y:1).
> a add: (Point x: 2 y:2).
> a add: (Point x: 2 y:3).
> b := a asSortedCollection: [:p1 : p2 | (p1 x < p2 x) and: [p1 y < p2 y]].
> results in this: a SortedCollection(2@1 1@3 1@1 2@2 1@2 2@3)
>
> I know I am overlooking something real simple, but why isn't this major
> minor sort working. Thanks.

Don,

if p1 x < p2 x is false, then the points are swapped, regardless of the y
component.
(Lazy evaluation). (see False>>and:)

Ingo


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

Ingo Blank
In reply to this post by jWarrior
> a := OrderedCollection new.
> a add: (Point x: 1 y:1).
> a add: (Point x: 1 y:2).
> a add: (Point x: 1 y:3).
> a add: (Point x: 2 y:1).
> a add: (Point x: 2 y:2).
> a add: (Point x: 2 y:3).


Don,

in case you want a solution, here is one possible:

b := a asSortedCollection:[:p1 :p2| p1 x < p2 x].

result := OrderedCollection new.

idx := 1.

bSize := b size.

[idx <= bSize] whileTrue:[|tmp xGroup|

tmp := SortedCollection new sortBlock:[:p1 :p2 | p1 y < p2 y];yourself.

xGroup := (b at: idx) x.

[idx <= bSize and:[(b at: idx) x = xGroup]] whileTrue:[

tmp add: (b at: idx).

 idx := idx + 1

].

tmp do:[:e| result add: e]].



Bye

Ingo


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

Dave Harris-3
In reply to this post by jWarrior
[hidden email] (Donald MacQueen) wrote (abridged):
> b := a asSortedCollection: [:p1 : p2 |
>         (p1 x < p2 x) and: [p1 y < p2 y]].
> results in this: a SortedCollection(2@1 1@3 1@1 2@2 1@2 2@3)
>
> I know I am overlooking something real simple, but why isn't this major
> minor sort working. Thanks.

Because the sort block doesn't give a total ordering. Which do you think
is the smaller of 2@1 and 1@3? Try it:

    2@1 < 1@3:
        p1 x < p2 x ==> 2 < 1 ==> false
        p1 y < p2 y ==> 1 < 3 ==> true
           false and: [true] ==> false
       
    so 2@1 < 1@3 is false

Also:

    1@3 < 2@1:
        p1 x < p2 x ==> 1 < 2 ==> true
        p1 y < p2 y ==> 3 < 1 ==> false
            true and: [false] ==> false
           
    so 1@3 < 2@1 is false

Hence the sort has no way of knowing which Point to put first.

You probably want something like:

   b := a asSortedCollection: [:p1 :p2|
        (p1 x < p2 x) or: [(p1 x = p2 x) and: [p1 y < p2 y]]].

This only compares the y coordinates if the x coordinates are equal.
Another way to write it is:

   b := a asSortedCollection: [:p1 :p2|
        (p1 x ~= p2 x)
            ifTrue: [p1 x < p2 x]
            ifFalse: [p1 y < p2 y]].

which makes the symmetry a bit clearer. It's also easier to extend to
more levels (especially if we use a method instead, and so can do an
early return in the #ifTrue: branch).

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      [hidden email]      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

Ingo Blank
In reply to this post by Ingo Blank
"Ingo Blank" <[hidden email]> schrieb im Newsbeitrag
news:3b1c2fec$0$139$[hidden email]...

>
> "Donald MacQueen" <[hidden email]> schrieb im Newsbeitrag
> news:9fh9ah$94s$[hidden email]...
> > Evaluating this:
> > | a b c |
> > a := OrderedCollection new.
> > a add: (Point x: 1 y:1).
> > a add: (Point x: 1 y:2).
> > a add: (Point x: 1 y:3).
> > a add: (Point x: 2 y:1).
> > a add: (Point x: 2 y:2).
> > a add: (Point x: 2 y:3).
> > b := a asSortedCollection: [:p1 : p2 | (p1 y < p2 y) ].
> > results in this: a SortedCollection(2@1 1@1 1@2 2@2 1@3 2@3)
> >
> > But evaluating this:
> > | a b c |
> > a := OrderedCollection new.
> > a add: (Point x: 1 y:1).
> > a add: (Point x: 1 y:2).
> > a add: (Point x: 1 y:3).
> > a add: (Point x: 2 y:1).
> > a add: (Point x: 2 y:2).
> > a add: (Point x: 2 y:3).
> > b := a asSortedCollection: [:p1 : p2 | (p1 x < p2 x) and: [p1 y < p2
y]].

> > results in this: a SortedCollection(2@1 1@3 1@1 2@2 1@2 2@3)
> >
> > I know I am overlooking something real simple, but why isn't this major
> > minor sort working. Thanks.
>
> Don,
>
> if p1 x < p2 x is false, then the points are swapped, regardless of the y
> component.
> (Lazy evaluation). (see False>>and:)
>
> Ingo
>

Forget that!

Has nothing to do with lazy evaluation, but with "and" logic.
(A parallel version, i.e. (p1 x < p2 x) asParameter + (p2 y < p2 y)
asParamter == 2
 gives the same result)

If the first expression is false, then the pairs are swapped.
When comparing them at a later time, then the first expression evaluates to
true
and the second is evaluated. If this is now false too, then they are swapped
again, destroying the previous order. So you never get a two stage sort with
"and" logic.

Ingo


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

Randy A. Ynchausti-2
In reply to this post by jWarrior
Donald

> Evaluating this:
> | a b c |
> a := OrderedCollection new.
> a add: (Point x: 1 y:1).
> a add: (Point x: 1 y:2).
> a add: (Point x: 1 y:3).
> a add: (Point x: 2 y:1).
> a add: (Point x: 2 y:2).
> a add: (Point x: 2 y:3).
> b := a asSortedCollection: [:p1 : p2 | (p1 y < p2 y) ].
> results in this: a SortedCollection(2@1 1@1 1@2 2@2 1@3 2@3)

[ snip ]

I think you want the following:

| a b |
a := OrderedCollection new.
a add: (Point x: 1 y:1).
a add: (Point x: 1 y:2).
a add: (Point x: 1 y:3).
a add: (Point x: 2 y:1).
a add: (Point x: 2 y:2).
a add: (Point x: 2 y:3).
b := a asSortedCollection: [:p1 : p2 |
 ( p1 x < p2 x )
  ifTrue: [ true ]
  ifFalse: [ p1 x = p2 x and: [ p1 y < p2 y ] ] ].

Which yields:

SortedCollection (1@1 1@2 1@3 2@1 2@2 2@3)


Hope that helps!

Regards,

Randy


Reply | Threaded
Open this post in threaded view
|

Re: I'm confused

jWarrior
Doh! (sound of head slap).

What -was- I thinking! Thanks to all who set me back
on the path of truth and enlightenment.

"Randy A. Ynchausti" <[hidden email]> wrote in message
news:nI4T6.13$[hidden email]...

> Donald
>
> > Evaluating this:
> > | a b c |
> > a := OrderedCollection new.
> > a add: (Point x: 1 y:1).
> > a add: (Point x: 1 y:2).
> > a add: (Point x: 1 y:3).
> > a add: (Point x: 2 y:1).
> > a add: (Point x: 2 y:2).
> > a add: (Point x: 2 y:3).
> > b := a asSortedCollection: [:p1 : p2 | (p1 y < p2 y) ].
> > results in this: a SortedCollection(2@1 1@1 1@2 2@2 1@3 2@3)
>
> [ snip ]
>
> I think you want the following:
>
> | a b |
> a := OrderedCollection new.
> a add: (Point x: 1 y:1).
> a add: (Point x: 1 y:2).
> a add: (Point x: 1 y:3).
> a add: (Point x: 2 y:1).
> a add: (Point x: 2 y:2).
> a add: (Point x: 2 y:3).
> b := a asSortedCollection: [:p1 : p2 |
>  ( p1 x < p2 x )
>   ifTrue: [ true ]
>   ifFalse: [ p1 x = p2 x and: [ p1 y < p2 y ] ] ].
>
> Which yields:
>
> SortedCollection (1@1 1@2 1@3 2@1 2@2 2@3)
>
>
> Hope that helps!
>
> Regards,
>
> Randy
>
>
>