Notifications
Clear all

[Closed] How to convert a file into an array with sublevels ?

Hi guys,

Let us say that I define an array in a file.

the file:

(
a1
a2
	(
	b1
	b2
		(
		c1
		c2
		)
	b3
	)
a3
	(
	b4
		(
		c3
		)
	b5
	)
)

For practical reasons, I converted this file into an linear array:

thefile=#("(","a1", "a2", "(", "b1", "b2", "(", "c1", "c2", ")", "B3", ")", "a3", "(", "b4", "(", "c3", ")", "b5", ")",")")

Now I would like to transform this file into an array with sublevels.
Here the expected result written by hand:
#(a1,a2,#(b1,b2,#(c1,c2),b3),a3,#(b4,#(c3),b5))

How do you make that ?
I tested several recursive functions but without success.
Of course I cannot just add # in front of ( and some commas

Can anyone point me in the right direction ? Thanks

22 Replies

heres some pretty basic pseudocode to get you going:

new array anArray

position = 0
while (elt != flag)
(
anArray append elt
elt = getElement file position != flag
)

getElement file possition
(
if token file position == “(” then
(
new array2
while token file position != “)”
(
advance position
array2.append token
)
return array2
) else
return token

)

This code is pretty similar to the functions that I have tried.
But there are no recursive logic and because of that the array is not yet correct.

Test this code:

fn readBloc array pos =
	(
	if pos>array.count
		then false
		else (
			end=pos
			bloc=0
			do (
				if array[end]=="(" then bloc+=1
				if array[end]==")" then bloc-=1
				end+=1
				)
			while ( bloc>0 and end<=array.count )
			if pos==(end-1)
				then array[pos]
				else ( newArray=for i=pos to (end-1) collect array[i] )
			)
	)--fn

fn getArrayFromPseudoFile pseudoFile =
	(
	newArray=#()
	position=1
	element=true
	while element!=false do
		(
		element=readBloc pseudoFile position
		if element!=false do append newArray element
		if classof element==Array
			then position+=element.count
			else position+=1
		)--while
	format "

newArray=%
" newArray		
	format "
print newArray

"
	print newArray
	format "
===========
"
	)--fn

clearListener()
pseudoFile=#("a1", "a2", "(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")", "a3", "(", "b4", ")","a4")
getArrayFromPseudoFile pseudoFile

the array:

a1
a2
	(
	b1
	b2
		(
		c1
		c2
		)
	b3
	)
a3
	(
	b4
	)
a4

The function return this array:

newArray=#("a1", "a2", #("(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")"), "a3", #("(", "b4", ")"), "a4")

print newArray

"a1"
"a2"
#("(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")")
"a3"
#("(", "b4", ")")
"a4"

As you can see the result is not yet correct.
Nevertheless Thanks for your help. It is a step moreover towards the solution.
It misses a recursive logic.

Does somebody have an idea?

I have just found a solution.

fn arrayTransformer array =
	(
	pos=1
	startBloc=0
	while ( array[pos]!=")" and pos<=array.count) do
		(
		if array[pos]=="(" do startBloc=pos
		pos+=1
		)
	if startBloc==0 then false
	else (
		startArray=for i=1 to startBloc-1 collect array[i]
		blocArray=for i=startBloc+1 to pos-1 collect array[i]
		endArray=for i=pos+1 to array.count collect array[i]
		startArray+#(blocArray)+endArray
		)
	)--fn

fn arrayStructureFinder array =
	(
	retValue=array
	do (
		array=retValue
		retValue=arrayTransformer array
		)
	while retValue!=false
	array
	)--fn

pseudoFile=#("a1", "a2", "(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")", "a3", "(", "b4", ")","a4")
structuredArray=arrayStructureFinder pseudoFile

clearListener()
format "structuredArray=%
" structuredArray

It requires many manipulations in memory.
I do not think that it is the ideal solution… but It works.
If somebody has a better method. I am still interested to know it.

Have a good day.

I’ts inefficient because you uneccessarily make many copies of the array.

You should make one function that can return either an element or an array. This function should call itself in order to find the next element if it’s going to be returning an array.

In the place where I wrote “array2.append token”, if you replace that with a call to “getElement” then it will be recursive and the concept of it will work.

Ok I restart from the begining.
If you help me a bit, I could write an optimized script.
First I convert your pseudo code in maxscript.

I make some modifications.
I add the variable ‘bloc’ to avoid an error : the function would return
an incomplete structure if it stopped with the first “)”

ok after that getElement return:

getElement pseudoFile 2
==> "a2"
getElement pseudoFile 6
==> #("c1", "c2")
getElement pseudoFile 3
==> #("b1", "b2", "(", "c1", "c2", ")", "b3")

There is not yet an recursive logic. But do you agree with the results ?

The script:

fn getElement array position =
	(
	if position>array.count then false
	else
		(
		if array[position]=="("
			then (
				position+=1
				bloc=1
				array2=#()
				while ( bloc>0 and position<=array.count ) do
					(
					append array2 array[position]
					position+=1
					if array[position]=="(" then bloc+=1
					if array[position]==")" then bloc-=1
					)
				array2
				)
			else array[position]
		)
	)

pseudoFile=#("a1", "a2", "(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")", "a3", "(", "b4", ")","a4")
anArray=#()
position=1
count=1
elt=getElement pseudoFile position
while (elt != false) do
	(
	if classof elt==Array then position+=elt.count else position+=1
	append anArray elt
	elt=getElement pseudoFile position
	)
format "anArray=%
" anArray

The next step is to add the recursive call.

I have just found the code recursive

fn arrayFromFile array pos =
	(
	newArray=#()
	while pos<=array.count do
		(
		if ( array[pos]!="(" and array[pos]!=")" )
			then (append newArray array[pos])
			else (
				if array[pos]=="(" do
					(
					nextPos=pos+1
					pos+=1
					bloc=1
					array2=#()
					while ( bloc>0 and pos<=array.count ) do
						(
						append array2 array[pos]
						pos+=1
						if array[pos]=="(" then bloc+=1
						if array[pos]==")" then bloc-=1
						)
					append newArray (arrayFromFile array2 1)
					)
				)
		pos+=1
		)
	newArray
	)

clearListener()
pseudoFile=#("a1", "a2", "(", "b1", "b2", "(", "c1", "c2", ")", "b3", ")", "a3", "(", "b4", ")","a4")
structuredArray=arrayFromFile pseudoFile 1
format "structuredArray=%
" structuredArray

stuh505 thanks for your help. You pointed me in the right direction.

Here’s a more concise way of doing it. By the way you don’t need to use recursion, you could use a list to store temporary lists as a kind of stack. How do you paste code with indentation?


fn sublevelarray list=
(
pos=0
return (getNextSublevel list)
)
 
fn getNextSublevel list =
(
pos+=1
 
if (pos > list.count) then
return
if (list[pos]==")") then
return ")"
if (list[pos]=="(") then
(
newArray=#()
 
while ((ret = getNextSublevel list) != ")") do
append newArray ret
 
return newArray
)
 
return list[pos]
)
 

myarray=#(“(“,“1”,“2”,”(“,“3”,“4”,”)”,”)”)
sublevelarray myarray

EDIT: I wrote mine to deal with an original list that has “(” and “)” at the front and back

Oh easy. I copy/paste from maxscript editor. I select my script and press # in toolmenu of the post editor. That adds the header ‘CODE’ to keep the indentation.
[CO_DE]code with identation[/CO_DE] (remove the “_”)

1
	2
		3

If you use an another editor, try this to remove the special format: open notepad and press CTRL+V(paste),CTRL+A(select all),CTRL+X(cut)

Could you post your code with indentation ?
Thanks

 
fn sublevelarray list=
(
 pos=0
 return (getNextSublevel list)
)
fn getNextSublevel list =
(
 pos+=1
 
 if (pos > list.count) then
  return
 if (list[pos]==")") then
  return ")"
 if (list[pos]=="(") then
 (
  newArray=#()
  
  while ((ret = getNextSublevel list) != ")") do
   append newArray ret
  
  return newArray
 )
 
 return list[pos]
)
myarray=#("(","1","2","(","3","4",")",")")
sublevelarray myarray

Page 1 / 3