Load 'tree' from file

BlitzMax Forums/BlitzMax Programming/Load 'tree' from file

rs22(Posted 2016) [#1]
My program outputs a list of items like the following. It saves the 'indent level' and then the name of the item.

0	Item
0	Item
1		SubItem
2			SubSubItem
1		SubItem
1		SubItem
0	Item
1		SubItem
2			SubSubItem
3				SubSubSubItem 


How would I go about loading that back into a linked list?


Henri(Posted 2016) [#2]
Hi,

I would probably create 2 Types for this:

First type is an 'interface' type which holds all the functionality like 'CreateNode' or 'AddNode' or 'SaveToFile' or 'LoadFromFile' or 'ShowAllÍtems' etc. and it would also contain a TList which holds the actual data hence forth known as 'nodes'.

Second type is a 'data' type or 'Node' which holds information of that item like 'name' or 'color' etc. and it has 2 basic components: 'Parent node' and 'child node'. If there is no parent then you would know that it's the first in line and if there is no child then you 'd know that it's the last in line.

When you iterate list do something like:
For Local node:TNode = EachIn list
	
	If Not node.parent 'First node
		Print node.name
	Else
		Print "~t" + node.name
	EndIf
Next


Anyway this is just a basic idea, implemention depends on the need / purpose.

-Henri


rs22(Posted 2016) [#3]
Thanks for the reply. I'm having a hard time figuring this out. It's probably much simpler than I'm making it.

I forgot to say in my first post that the output is to a file. It writes an integer for the indent level, and then the name of the item. It's easy to read them all back if you don't need to worry about subitems.


Dabhand(Posted 2016) [#4]
This smells like a job for XML! :)

http://www.blitzbasic.com/Community/posts.php?topic=68699

Dabz


Henri(Posted 2016) [#5]
Ok, lets assume that text file is in a format descriped in 1# post then something like this could suffice:
Strict

Local file:TStream = OpenStream("my_file.txt")
If Not file Then Notify("file not found!"); End

Local list:TList = New TList, item:TItem

While Not Eof(file)
	
	Local s:String = ReadLine(file)
	If Not s Then Continue
	
	Local data:String[] = s.split("~t")
	If Not data Then Continue
	
	item = New TItem
	item.indent = Int(data[0])
	item.name = data[data.length - 1]
	list.addlast(item)
Wend

CloseStream(file)

'Iterate our list. Just for fun we add tabs also.
Local tabs:String

For item = EachIn list

	For Local i:Int = 0 To item.indent
		tabs:+ "~t"
	Next
	
	Print item.indent + tabs + item.name
	
	tabs = ""
Next

End


Type TItem
	Field indent:Int
	Field name:String
EndType


-Henri


Hardcoal(Posted 2016) [#6]
Ive made a database for that.
It works fine for my needs

https://www.dropbox.com/s/3d7rnr14xyugy7y/MyDataBaseV2.bmx?dl=0


markcw(Posted 2016) [#7]
This is similar to something I'm working on, code folding. It uses levels to determine if a fold is in another fold.

To reload the data:
- if it's just 2 things you're associating use a map key+value, if you need to access chronologically you can also store the keys in a list as MapKey loops are ordered like 1,11,2,12 instead of 1,2.
- for more than 2 add the data to a space separated string and then parse that in a function or use a custom type and store the objects in a list.


Brucey(Posted 2016) [#8]
This smells like a job for XML

I'm tending toward JSON these days, since it's what I appear to work with all the time... (for example Vert.x uses it for its interprocess communication).


rs22(Posted 2016) [#9]
I've started using XML with Brucey's libxml module. Thanks for it, Brucey!

I like it better than the method I was using before. I think it has advantages that make it more suitable for me.

However, I'm still struggling with getting the XML nodes loaded into a linked list. I can't find an example of it anywhere, either. Does anyone have an example of such a thing?