VL-SORT w/architecture values

VL-SORT w/architecture values

Anonymous
Not applicable
1,489 Views
12 Replies
Message 1 of 13

VL-SORT w/architecture values

Anonymous
Not applicable

I'd like to sort a list of dotted pairs based on their key.  I'm using this chunk of code I found on the Autocad website.

(SETQ LIST
   (VL-SORT LIST
    '(LAMBDA (b a) (< (CAR b) (CAR a))
    )
    )
  ) 

_$LIST

((10'-0" . 4.0) (11'-0" . 2.0) (12'-0" . 4.0) (8'-4 3/4" . 18.0) (8'-6" . 4.0) (9'-6" . 4.0))

 

I think I see how its sorting them. . . That's just not what I want. I'd like them to start with the smallest value. Lisp is new to me, so it's probably something really simple. I'll eventually use these key/values to populate a table. I'm not sure if that consideration is important. But it's something to keep in mind.

 

Thanks for any input.

 

0 Likes
Accepted solutions (1)
1,490 Views
12 Replies
Replies (12)
Message 2 of 13

Kent1Cooper
Consultant
Consultant

Try this [untested]:

(SETQ LIST
   (VL-SORT LIST
     '(LAMBDA (b a) (< (distof (CAR b)) (distof (CAR a))))
   )
) 

That's assuming the first items in the sub-lists are not as you show them [it doesn't seem possible], but are text strings, i.e.:
(("10'-0\"" . 4.0) ("11'-0\"" . 2.0) ....

Kent Cooper, AIA
Message 3 of 13

Anonymous
Not applicable

Oh, it outputs what is shown in the OP. I'm using (RTOS) to convert selection set data w/my drawing units set to Architecture. Otherwise it just outputs the 'Length data object in inches without notation.

 

Output w/out RTOS:

_$ ((100.75 . 18.0) (102.0 . 4.0) (114.0 . 2.0) 

 

TBH, I'd rather sort w/inch values and convert to Architectural later. However, there are some bugs I can't seem to work out when using the above method w/out RTOS.  So If I could get the OP version organized that would be awesome.

 

Thanks so much for the help.

0 Likes
Message 4 of 13

pbejse
Mentor
Mentor

@Anonymous wrote:

 


TBH, I'd rather sort w/inch values and convert to Architectural later. However, there are some bugs I can't seem to work out when using the above method w/out RTOS.  So If I could get the OP version organized that would be awesome.

 

(setq notconvertedlist '((100.75 . 18.0) (102.0 . 4.0) (114.0 . 2.0)))
(setq convertedlist
       (mapcar '(lambda	(v)
		  (list (Rtos (Car v) 4) (cdr v))
		)
	       (vl-sort	notconvertedlist
			'(lambda (b a)
			   (< (car b) (car a))
			 )
	       )
       )
)

What bug is that?

 

 

Message 5 of 13

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

Oh, it outputs what is shown in the OP. .... 

Output w/out RTOS:

_$ ((100.75 . 18.0) (102.0 . 4.0) (114.0 . 2.0) 

....


But with  RTOS, doesn't it give output with the first elements in the dotted pairs as text strings, such as this, rather than as shown in the first Post?

 

(setq test '(("10'-0\"" . 4.0) ("11'-0\"" . 2.0) ("12'-0\"" . 4.0) ("8'-4 3/4\"" . 18.0) ("8'-6\"" . 4.0) ("9'-6\"" . 4.0)))

 

[and I'm using 'test' rather than 'list' -- using an AutoLisp function name as a variable name invites trouble.]

 

Given a list like that, my earlier suggestion:


(SETQ test (VL-SORT test '(LAMBDA (b a) (< (distof (CAR b)) (distof (CAR a))))))

 

returns them sorted in ascending order of first-item lengths, rather than by first character:


(("8'-4 3/4\"" . 18.0) ("8'-6\"" . 4.0) ("9'-6\"" . 4.0) ("10'-0\"" . 4.0) ("11'-0\"" . 2.0) ("12'-0\"" . 4.0))

Kent Cooper, AIA
Message 6 of 13

Anonymous
Not applicable

Hi Kent,

Thanks again for your time. So I'm saying this w/the caveat that this is my first real attempt at a autolisp script; so I'm probably over looking something very simple.

But the short answer is: No. Smiley Sad

It outputs exactly as shown when using the RTOS function. There are not extra quotations or slashes. It's what you see in the OP. This output dumps to the command line, not the vlisp console. Not sure if that matters, but it's what I've been using to navigate the various values while I build this. 

(PRINC DOTTEDLIST)

 I tried that snippet you offered earlier and it started throwing something about a function error. Lets keep digging and see what we find out. I think it's converting the REAL to the correct characters b/c it's either:

A: Printing like that to the command line, and the Command line knows that its supposed to convert it.

-OR-

B: RTOS recognizes that it's 'Length object/<entity> data in a drawing w/units set to Architecture.

Whatever it is, I hope I can get it. It's already at a useable state, but getting a proper clean output to a table will be super cool. 

0 Likes
Message 7 of 13

Anonymous
Not applicable

Hey Pbejse,

 

So the bug isn't shown above. Thats not the complete output. Here it is though:

>_(mynewfunction)
>_ Select Objects:
>_ Select Parameter Args:
>_ Table List : (list of dotted pairs)

The function is supposed to add to the values in the dotted pairs as it iterates through the selection set. So each Key has it's own Cons w/some number that says how many there are. 

Here's the bug when it's ran w/out (RTOS):

LIST ((100.75 . 18.0) (102.0 . 4.0) (114.0 . 2.0) (114.0 . 2.0) (120.0 . 2.0) (120.0 . 2.0) (132.0 . 2.0) (144.0 . 4.0))

The underlined key/values should not yield 2 instances. However, it should add those dotted pair values and only give one instance of the key.

Oddly enough, When I include the RTOS on the car values here, it adds them correctly. 

See below:

 LIST ((10'-0" . 4.0) (11'-0" . 2.0) (12'-0" . 4.0) (8'-4 3/4" . 18.0) (8'-6" . 4.0) (9'-6" . 4.0))

You'll notice here the values are not organized by size though, as they are the in the list above this one. Feels like I'm stuck between a rock and hard place. The sort script listed in the OP is included in both functions here.

 

You guys are great, and thanks for all the help.

 

Thanks for the guys.

0 Likes
Message 8 of 13

pbejse
Mentor
Mentor

@Anonymous wrote:

Hey Pbejse,

.....The underlined key/values should not yield 2 instances. However, it should add those dotted pair values and only give one instance of the key...

 

 

 


I'm guessing you are using assoc to test if the current value being process already exists on your list correct?
Use the function equal instead of assoc as you are probably dealing with high precision values.

 

Holler if you need help.

 

 

 

Message 9 of 13

Kent1Cooper
Consultant
Consultant
Accepted solution

@Anonymous wrote:

.... I think it's converting the REAL to the correct characters b/c it's either:

A: Printing like that to the command line, and the Command line knows that its supposed to convert it.

.... 


That's got to be what it is.  It displays those without the additional quotes/slashes when asked to (princ) them, but it doesn't actually store  them that way.  Using the result from my earlier message after sorting, as displayed  from (princ):

 

Command: (princ test)
((8'-4 3/4" . 18.0) (8'-6" . 4.0) ....

 

but the actual list itself, as stored:


Command: !test
(("8'-4 3/4\"" . 18.0) ("8'-6\"" . 4.0) ....

Kent Cooper, AIA
Message 10 of 13

Anonymous
Not applicable

I'm not sure where I went wrong before, but this handled it when I ran it again. It probably just needed a good stare down Smiley Mad , or for me to put the code in correctly. 

 

It's been great. I appreciate all the input.

0 Likes
Message 11 of 13

pbejse
Mentor
Mentor

FWIW

An example

 

 

(setq test1 '(45.00 114.000123 23.56 114.000113 114.000135))
(45.0 114.0 23.56 114.0 114.0) <---- 

(foreach itm test1
  (setq	collectedlist
	 (if (setq f (assoc itm collectedlist))
	   (subst (cons itm (+ (cdr f) 1)) f collectedlist)
	   (cons
	     (cons itm 1)
	     collectedlist
	   )
	 )
  )
)
((114.0 . 1) (114.0 . 1) (23.56 . 1) (114.0 . 1) (45.0 . 1))
(foreach itm test1 (setq collectedlistvlsome (if (setq f (vl-some '(lambda (v) (if (equal (car v) itm 1e-3) v)) collectedlistvlsome)) (subst (cons itm (+ (cdr f) 1)) f collectedlistvlsome) (cons (cons itm 1) collectedlistvlsome ) ) ) )
((23.56 . 1) (114.0 . 3) (45.0 . 1)) (setq RtosedList (mapcar '(lambda (v) (list (Rtos (Car v) 4) (cdr v)) ) (vl-sort collectedlistvlsome '(lambda (b a) (< (car b) (car a)) ) ) ) )

HTH

 

0 Likes
Message 12 of 13

Anonymous
Not applicable

Pb,

 

I thought about using your "EQUAL" and realized that I'd rather avoid it. The only reason is because its going to lead to another IF statement, and I'm already nested once. Currently the ASSOC that returns a value is not only validating the condition as True, but it's also using the output to merge values into my list. . . I think I said that right. The original response that included the (DISTOF) function cleared it up. If it starts throwing silly values later, I may revert back to the (EQUAL) function and just RTOS after creating the list. 

 

I appreciate all the help you two gave me, and can finally move onto the table part of this project.

Whew.Smiley Surprised

0 Likes
Message 13 of 13

Anonymous
Not applicable

Pb

 

This pretty much how i'm building my list:

IF

  WHILE

    IF

      IF (SETQ ITM (ASSOC...

... 
I just realized that's nested more than 2. hmmm... I'm gonna keep it for now. Your way looks way easier. I'm still learning how the conditionals work. But will consider your code if I can't keep what I have working.

0 Likes