combining list to new list

combining list to new list

DGRL
Advisor Advisor
3,008 Views
10 Replies
Message 1 of 11

combining list to new list

DGRL
Advisor
Advisor

Dear coders,

 

Have a very simple coding question.

As a noob in coding i just cant figure this out until now

I have a list and looks like this
(("somedata" "somedata01" "ect")("Somedata1" "somedata2" "ect1"))

 

What i want is a piece of code that will make a new list out of this one but then looks like this

 

(("somedata" "Somedata1")("somedata01" "somedata2")("ect" "ect1"))

 

I was thinking to do this with a foreach but it does not work

(foreach att (car a)
(setq lst (list (car a)))
(setq lst (list (append (cdr a) lst)))

)

Kind regards

 

 

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Accepted solutions (1)
3,009 Views
10 Replies
Replies (10)
Message 2 of 11

martti.halminen
Collaborator
Collaborator

You could do this also with FOREACH, but this is another way:

 

(defun collect3 (data)
  ;; ((a1 b1 b2)(a2 b2 c2)...) => ((a1 a2 ...)(b1 b2 ...)(c1 c2 ...))
  (list (mapcar (function car) data)
        (mapcar (function cadr) data)
        (mapcar (function caddr) data)))

-- 

 

0 Likes
Message 3 of 11

martti.halminen
Collaborator
Collaborator

typo in the comment, another try:

 

(defun collect3 (data)
  ;; ((a1 b1 c1)(a2 b2 c2)...) => ((a1 a2 ...)(b1 b2 ...)(c1 c2 ...))
  (list (mapcar (function car) data)
        (mapcar (function cadr) data)
        (mapcar (function caddr) data)))

--

0 Likes
Message 4 of 11

_gile
Consultant
Consultant
Accepted solution

Hi,

 

If data only contains 2 lists, you can simply do:

(mapcar 'list (car data) (cadr data))

But a more generic way working whatever the number of lists in data is:

(apply 'mapcar (cons 'list data))


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 11

Moshe-A
Mentor
Mentor

this will work....but what do you want to do with the "ect" "ect1" if your list would contain more the 2 items?

cause this one will put all of them as the last item list

 

 

(setq newData '() lastData '())
(foreach item '(("somedata" "somedata01" "ect")("Somedata1" "somedata2" "ect1"))
 (setq lastData (append lastData (list (last item))))
 (setq newData (append newData (list (reverse (cdr (reverse item))))))
)

(append newData (list lastData))
0 Likes
Message 6 of 11

DGRL
Advisor
Advisor

This 1 seems to work but only process 3 lists not all
Since i don not know how much entry's i have

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 7 of 11

DGRL
Advisor
Advisor

@_gile


This line works perfect but when i open block editor the old names are still there

DO i need to endmod this dwg?

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 8 of 11

_gile
Consultant
Consultant

The expression I purposed only returns a new list.

I can not say anything more because I do not know anything about how you use the returned list.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 9 of 11

DGRL
Advisor
Advisor

@_gile

Indeed lol

you did not made the routine that changes the tags
As i wanna learn i will search for a solution before i ask more help

 

Thanks for your time so far 🙂

Kind regards

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 10 of 11

DGRL
Advisor
Advisor

@_gile

May i kindly ask your help again?
In the end i want to be able to do this.

and a lot is already working


1. extract from xls old att

2. extract from xls new att

Point 1 and 2 are done thanks to your piece of code

now i need to do following ( i will show code i use below )
The list looks like this ( more then 3 entry's offcourse)
(("ISO_PIPESPEC" "n.v.t.") ("ISO_MEDIUM" "n.v.t.") ("ISO_DESIGN_PRESS" "n.v.t.")

what needs to be done is adding 2 more things to each individual list
So it will looks like this

(("ISO_PIPESPEC" "n.v.t." "extra1" extra2") ("ISO_MEDIUM" "n.v.t." "extra4" extra5") ("ISO_DESIGN_PRESS" "n.v.t." "extra6" extra7")

Ofcourse extra1 is just a sample name

Why do i want this
I need to change old ATT TAGS into new ones
and i need to update the ATT value with a field that is linked to customdwgprop

To add the info i need in dwg props i use something like this

(setq App (vlax-Get-Acad-Object)
Doc (vla-Get-ActiveDocument App)
DwgProps (vla-Get-SummaryInfo Doc))

;(setq lst '("a" "b" "c" "d"))
; Var b is the list made with the renameTAGG.lsp
(foreach lstt b
(setq c (car lstt))
(setq d (cadr lstt))
(vla-AddCustomInfo DwgProps c d)


And for the ATT change part i use this
;;GET XLS WITH TAGS
(setq csv (findfile "attchange.xls"))
;;GET ALL OLD AND NEW TAGS
(setq a (getexcel csv "Pipe Line Group" nil))
;;OLD TAG
(setq b (car a))
;;NEW TAG
(setq c (cadr a))
;;PROMPT
(setq d nil)
(setq str   (strcat "%<\\AcVar CustomDP." c " \\f \"%tc3\">%")) <-- this one is used to make a field linked to dwgpropname


  (setq tagLst ; All tags must be upper case.
    (list
      ;     OLD TAG NEW TAG PROMPT VALUE
      (list b c d str) ; \U+00A0 = Unicode non-breaking space.
      ;(list "SHT_CALL_ON" "ITEM_$" "PROMPTSTRING2" "VALUE2")
    )
  )

  (setq doc (vla-get-activedocument (vlax-get-acad-object)))
  (vla-endundomark doc)
  (vla-startundomark doc)
  (vlax-for blk (vla-get-blocks doc)
    (if (= :vlax-false (vla-get-isxref blk))
      (vlax-for obj blk
        (cond
          ((= "AcDbBlockReference" (vla-get-objectname obj))
            (if (= :vlax-true (vla-get-hasattributes obj))
              (foreach att (vlax-invoke obj 'getattributes)
                (if (setq new (assoc (vla-get-tagstring att) tagLst))
                  (progn
                    (vla-put-tagstring att (cadr new))
                    (vla-put-textstring att (cadddr new))
                  )
                )
              )
            )

          )
          ((= "AcDbAttributeDefinition" (vla-get-objectname obj))
            (if (setq new (assoc (vla-get-tagstring obj) tagLst))
              (progn
                (vla-put-tagstring obj (cadr new))
                (vla-put-textstring obj (cadddr new))
                (vla-put-promptstring obj (caddr new))
              )
            )
          )
        )
      )
    )
  )
  (vla-endundomark doc)
  (princ)


Maybe you know a quicker and better way or maybe you can fix this 🙂

Kind regards

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
0 Likes
Message 11 of 11

_gile
Consultant
Consultant

You should only replace tags in the attribute definitions of the block definitions and regen at the end of the routine.

 

  (vlax-for blk (vla-get-blocks doc)
    (if (= :vlax-false (vla-get-isxref blk))
      (vlax-for obj blk
        (if (and
              (= "AcDbAttributeDefinition" (vla-get-objectname obj))
              (setq new (assoc (vla-get-tagstring obj) tagLst))
            )
          (progn
            (vla-put-tagstring obj (cadr new))
            (vla-put-textstring obj (cadddr new))
            (vla-put-promptstring obj (caddr new))
          )
        )
      )
    )
  )


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub