bmx-ng / brl.mod

BlitzMax Runtime Libraries, for BlitzMax NG.
12 stars 11 forks source link

TIntMap._FirstNode returns new node, not first node #60

Open GWRon opened 6 years ago

GWRon commented 6 years ago

This is TIntMap's _FirstNode:

    Method _FirstNode:TIntNode()
        If Not IsEmpty() Then
            Local node:TIntNode= New TIntNode
            node._root = _root
            Return node
        Else
            Return Null
        End If
    End Method

This is TMap's _FirstNode:

    Method _FirstNode:TNode()
        Local node:TNode=_root
        While node._left<>nil
            node=node._left
        Wend
        Return node
    End Method

TMap will traverse from _root to the first node, TIntMap will return a new node instead.

Example:

SuperStrict
Framework Brl.StandardIO
Import Brl.Map

Local mymap:tintmap=New tintmap
mymap.insert(1,"one")
mymap.insert(2,"two")
mymap.insert(3,"three")

Local m:TIntNode = mymap._firstnode() 'root
'uncomment to make it work
'm=m.nextnode()
While m<>Null
        Local v:String = String(m.value())
        m=m.nextnode()
Wend

Bug source: https://www.syntaxbomb.com/index.php/topic,4187.15.html

woollybah commented 6 years ago

I should make _firstNode() private :-)

On 27 Feb 2018, at 11:16, Ronny Otto notifications@github.com wrote:

This is TIntMap's _FirstNode:

Method _FirstNode:TIntNode() If Not IsEmpty() Then Local node:TIntNode= New TIntNode node._root = _root Return node Else Return Null End If End Method



This is TMap's `_FirstNode`:
Method _FirstNode:TNode()
  Local node:TNode=_root
  While node._left<>nil
      node=node._left
  Wend
  Return node
End Method

TMap will traverse from _root to the first node, TIntMap will return a new node instead.

Example:
```BlitzMax
SuperStrict
Framework Brl.StandardIO
Import Brl.Map

Local mymap:tintmap=New tintmap
mymap.insert(1,"one")
mymap.insert(2,"two")
mymap.insert(3,"three")

Rem
Local m:TIntNode = mymap._firstnode() 'root
'uncomment to make it work
'm=m.nextnode()
While m<>Null
        Local v:String = String(m.value())
        m=m.nextnode()
Wend
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
GWRon commented 6 years ago

How to fetch the first node of the map then?

woollybah commented 6 years ago

What do you need the first node of a map for?

On 27 Feb 2018, at 12:18, Ronny Otto notifications@github.com wrote:

How to fetch the first node of the map then?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

GWRon commented 6 years ago

See the example - the original requestor tried to iterate over the TIntMap with the "While node ... node.NextNode()" appraoch.

GWRon commented 6 years ago

Which was btw suggested by you - when you optimized the original TMap usage in TVTower :-)

woollybah commented 6 years ago

It returns a new TIntNode because a TIntNode is just a placeholder to allow you to iterate the map.

_FirstNode() is marked as private in TMap, therefore is presumed undocumented, and therefore you'll need to look at the code to see how to use it correctly.

The same applies to TIntMap. If you insist on using undocumented features, you'll need to use it properly :

SuperStrict
Framework Brl.StandardIO
Import Brl.Map

Local mymap:tintmap=New tintmap
mymap.insert(1,"one")
mymap.insert(2,"two")
mymap.insert(3,"three")

Local m:TIntNode = mymap._firstnode() 'root

While m And m.HasNext()
    m = m.NextNode()
    Print String(m.value())
Wend
GWRon commented 6 years ago

Yes but it seems people tried it and because it works that way with TMap they assumed it worked the same with TIntMap. I would assume that too.

Think "FirstNode" is self-describing as "first node in the map". I would even assume that "root" (if public) is the first node of such a map. People do not care of how underlaying stuff works. They assume "natural" behaviour. The root node is some kind of "odd" as only of internal use.