TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Pepe on October 06, 2010, 03:47:05 PM
-
Hi!
I have a list of lists. Each one of the sub-lists has two elements. The first one is also a list that shows a hierarchy, and the second is a name. p.e.
(((1) "OneName") ((0 1) "Xampl") ((0 0 1) "Subname") ((1 0 1) "SpainIsDifferent") ((1 1) "AAI") ((0 1 1) "yVivaSanFermín") ((1 1 1) "VivaElVinoDeRioja"))
This list represents a tree like this:
1.-"OneName"
1.0.- "Xampl"
1.0.0.- "Subname"
1.0.1.- "SpainIsDifferent"
1.1.- "AAI"
1.1.0.- "YVivaSanFermín"
1.1.1.- "VivaElVinoDeRioja"
I want to sort the list alphabetically but keeping the hierachy, so the tree should remain like this:
1.-"OneName"
1.0.- "AAI"
1.0.0.- "VivaElVinoDeRioja"
1.0.1.- "YVivaSanFermín"
1.1.- "Xampl"
1.1.0.- "SpainIsDifferent"
1.1.1.- "Subname"
I'm a bit thick today, and I can't find a solution (nor explain it better... :cry:).
Would anybody help me, please? :angel:
-
So you want to sort on the first element list?
(caar '(((1) "OneName")
((0 1) "Xampl")
((0 0 1) "Subname")
((1 0 1) "SpainIsDifferent")
((1 1) "AAI")
((0 1 1) "yVivaSanFermín")
((1 1 1) "VivaElVinoDeRioja")))
(1)
If we sort on a list '(1 1 1) give an example of the next entry in the database?
I'm wondering why you need these particular pointers (1) (0 1) is there some binary requirement?
-
I want to sort the list alphabetically but keeping the hierachy, so the tree should remain like this:
1.-"OneName"
1.0.- "AAI"
1.0.0.- "VivaElVinoDeRioja"
1.0.1.- "YVivaSanFermín"
1.1.- "Xampl"
1.1.0.- "SpainIsDifferent"
1.1.1.- "Subname"
Perhaps I'm missing something, but how is that alphabetical?
-
It is on each hierachy level, so in that example he'd want AAI, Xampl, and Zoological sorted alphabetically, then have VivaElVinoDeRioja and YVivaSanFermín sorted alphabetically under AAI, and so on.
dJE
-
Oh I see it now, thanks for the pointer.
Sort on level 2 second item in the list.
Then re assign the pointers.
Is that correct?
-
break the list (keeping pointers)- though it doesn't look like you need to do this
sort
reassemble the list hierarchy (using pointers for relation not for order)
assign new pointers
do what cab said.
-
If we sort on a list '(1 1 1) give an example of the next entry in the database?
Thank you for the interest and sorry for answer so late (job, job, job...).
Next entry (just in the same list) should be quite similar:
(((2) "Another Item") ((0 2) "ILoveMyMom") ((0 0 2) "MyMomIsLovely") ((1 0 2) "AndMyCatToo")) ((1 2) "MyTaylorIsRich"))
And so on...
-
Heres an ugly idea that seems to work.
(defun stringlist (a / b c fn match sn)
(mapcar '(lambda (b) (if (= (cadr b) a)(setq fn (car b)))) alist)
(setq match (vl-remove-if
'(lambda (b)
(or
(/= (vl-list->string fn)(vl-list->string (cdr (car b))))
(/= (strlen (vl-list->string fn))(strlen (vl-list->string (cdr (car b)))))
)
)
alist
)
)
(mapcar '(lambda (c) (setq sn (acad_strlsort (append sn (list (cadr c)))))) match)
sn
);defun
(defun sortlist (zlist / )
(foreach x zlist
(setq slist (append slist (list x)))
(if (stringlist x) (sortlist (stringlist x)))
)
)
(defun finalsort ( alist / slist finalist)
(sortlist (cdr (nth 0 alist)))
(setq finalist (mapcar '(lambda (b c) (if b (list (car b) c) b)) alist slist))
finalist
)
(finalsort '(((1) "OneName") ((0 1) "Xampl") ((0 0 1) "Subname") ((1 0 1) "SpainIsDifferent") ((1 1) "AAI") ((0 1 1) "yVivaSanFermín") ((1 1 1) "VivaElVinoDeRioja")))
-
Hi,
IMO the most 'natural' way to build a tree in LISP is using nested lists.
Each node is a list which countains its child nodes as list too. the first item (car) in each node is the node name.
(setq tree
'(("OneName"
("Xampl"
("SubName")
("SpainIsDifferent")
)
("AAI"
("YVivaSanFermín")
("VivaElVinoDeRioja")
)
)
("Another Item"
("ILoveMyMom"
("MyMomIsLovely")
("AndMyCatToo")
)
("MyTaylorIsRich")
)
)
)
This kind of list is quite easy to sort using a recursive process:
(defun SortTree (lst)
(vl-sort (mapcar '(lambda (x)
(if (cdr x)
(cons (car x) (SortTree (cdr x)))
x
)
)
lst
)
'(lambda (x1 x2)
(< (car x1) (car x2))
)
)
)
(SortTree tree) returns:
(("Another Item"
("ILoveMyMom"
("AndMyCatToo")
("MyMomIsLovely")
)
("MyTaylorIsRich")
)
("OneName"
("AAI"
("VivaElVinoDeRioja")
("YVivaSanFermín")
)
("Xampl"
("SpainIsDifferent")
("SubName")
)
)
)
-
Some more functions using this kind of tree (examples using the upper defined tree list).
Get a node (ant its children) by its name:
(defun GetNode (node tree)
(if tree
(cond
((assoc node tree))
((GetNode node (apply 'append (mapcar 'cdr tree))))
)
)
)
_$ (GetNode "OneName" tree)
("OneName" ("Xampl" ("SubName") ("SpainIsDifferent")) ("AAI" ("YVivaSanFermín") ("VivaElVinoDeRioja")))
_$ (GetNode "ILoveMyMom" tree)
("ILoveMyMom" ("MyMomIsLovely") ("AndMyCatToo"))
Get a node by a list of index (note the list is 0 indexed and goes from higher level to deeper)
(defun GetNodeAt (ind tree)
(if tree
(if (cdr ind)
(GetNodeAt (cdr ind) (cdr (nth (car ind) tree)))
(nth (car ind) tree)
)
)
)
_$ (GetNodeAt '(0) tree)
("OneName" ("Xampl" ("SubName") ("SpainIsDifferent")) ("AAI" ("YVivaSanFermín") ("VivaElVinoDeRioja")))
_$ (GetNodeAt '(1) tree)
("Another Item" ("ILoveMyMom" ("MyMomIsLovely") ("AndMyCatToo")) ("MyTaylorIsRich"))
_$ (GetNodeAt '(0 1) tree)
("AAI" ("YVivaSanFermín") ("VivaElVinoDeRioja"))
_$ (GetNodeAt '(1 0 1) tree)
("AndMyCatToo")
-
Nice functions Gile :-)
I thought I'd try to write a 'GetIndexOf' function, but am really struggling :-( More coffee needed I think.
-
Nice explanation Gile.
Using nested lists is the way to go.
Pepe should use that and apply the prefix as needed later. i.e. (2) (0 2) etc.
-
For the LISP purist, lists are the way to go. But I'm a little dirty - I think XML would be better.
-
Thank you all for the hints! (Specially to Gile and Guitar_Jones.)
I haven't been able to visit this place as much as I'd like these past days, but I promise I'll meditate and think out how to use all this ideas during this weekend (a long one in Spain! ;-) ).
Thanks again! :-)
-
I thought I'd try to write a 'GetIndexOf' function, but am really struggling
Here's a way:
(defun GetIndexOf (node tree / foo1 foo2)
(defun foo1 (ind node tree)
(if tree
(if (assoc node tree)
(reverse (cons (vl-position (assoc node tree) tree) ind))
(foo2 (cons 0 ind) node tree)
)
)
)
(defun foo2 (ind node tree)
(if tree
(cond
((foo1 ind node (cdar tree)))
(T (foo2 (cons (1+ (car ind)) (cdr ind)) node (cdr tree)))
)
)
)
(foo1 nil node tree)
)
-
Very nice Gile - you make it look so easy 8-)