Jump to content

create set with repeated elements of two sets


robierzo

Recommended Posts

Hello. I have two sets (set1 and set2) with several elements. I need to create a new set (set3) with the repeated elements of both sets. Thank you

Edited by robierzo
Link to comment
Share on other sites

And how if you have 4 or more sets?

Maybe like this :

 

(defun MR:ListsIntersection ( ll / r l1 l2 )
  (while (and (setq l1 (car ll)) (setq l2 (cadr ll)))
    (setq r (vl-remove-if-not '(lambda ( x ) (member x l2)) l1))
    (setq ll (subst r l2 ll))
    (setq ll (cdr ll))
  )
  r
)

(MR:ListsIntersection '((1 3 5 2 4) (6 8 1 3 5) (9 0 1 3 5) (7 4 2 1 3) (1 3 5 7 9)))
;;; (1 3)

 

M.R.

Edited by marko_ribar
  • Like 1
Link to comment
Share on other sites

Posted (edited)

Hi Lee, hi Marco.
I use google translator. Maybe I haven't explained myself well.
I am referring to 2 selectionsets, S1 and S2, created using SSGET, for example.
(setq S1 (ssget...))
(setq S2 (ssget...))
S3 would be formed by the common elements of S1 and S2.
The solution you provide is valid. But I prefer a direct solution, without obtaining the lists of names beforehand.
Thank you.

Edited by robierzo
Link to comment
Share on other sites

Maybe like this :

 

(defun c:sss-intersection ( / MR:ListsIntersection-sel-sets ss lst ) 

  (defun MR:ListsIntersection-sel-sets ( ll / sel-set->ename-list ename-lists r l1 l2 rr k ) ;;; ll - list of sel.sets

    (defun sel-set->ename-list ( ss / i r )
      (repeat (setq i (sslength ss))
        (setq r (cons (ssname ss (setq i (1- i))) r))
      )
      r
    )

    (setq ename-lists (mapcar (function (lambda ( x ) (sel-set->ename-list x))) ll))
    (while (and (setq l1 (car ename-lists)) (setq l2 (cadr ename-lists)))
      (setq r (vl-remove-if-not '(lambda ( x ) (member x l2)) l1))
      (setq ename-lists (subst r l2 ename-lists))
      (setq ename-lists (cdr ename-lists))
    )
    (if r
      (progn
        (setq rr (ssadd) k -1)
        (repeat (length r)
          (ssadd (nth (setq k (1+ k)) r) rr)
        )
      )
    )
    (if (and (= (type rr) (quote pickset)) (> (sslength rr) 0))
      (sssetfirst nil rr)
    )
  )

  (prompt "\nChoose selections - when done press ENTER or right click...")
  (while (setq ss (ssget))
    (setq lst (cons ss lst))
  )
  (MR:ListsIntersection-sel-sets lst)
  (princ)
)

 

HTH.

M.R.

Edited by marko_ribar
  • Like 1
Link to comment
Share on other sites

i would just use

On 3/30/2024 at 10:40 AM, robierzo said:

I am referring to 2 selectionsets, S1 and S2, created using SSGET, for example.

 

I would use ssmemb then. this will create a global selection set SS3

 

;;----------------------------------------------------------------------------;;
;; Create a third selection set of values found in both selection sets provied
;; (ssint ss sss) 
(defun SSInt (SS1 SS2)
  (setq SS3 (ssadd)) ;create a blank selection set to add entitys to
  (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS1))) ;generate a list of entity names
    (if (ssmemb ent SS2) ;test if its in the other selection set
      (ssadd ent ss3) ;add to the 3rd selection set if true
    )
  )
  (princ)
)

 

 

Edited by mhupp
  • Like 1
Link to comment
Share on other sites

Doesn't ssadd add the entity if it is not there else it ignores it - so not sure you need the(if (ssmemb.....) ? 

 

 

(weekend.... )

  • Like 1
  • Agree 1
Link to comment
Share on other sites

I see what your saying could be condensed down to.

 

bad code

 

Quote

Return Values

If ename is a member of ss, ssmemb returns the entity name. If ename is not a member, ssmemb returns nil.

 

Edited by mhupp
  • Like 2
Link to comment
Share on other sites

@mhupp,

 

You cannot do (ssadd nil ss3) you will get an " error: bad argument type: lentityp nil". So you need the if clause.

 

;;SSint by mhupp                                                               ;;
;;                                                                             ;;
;; Return a selection set of Common element to both sets                       ;;
;;                                                                             ;;

(defun ssint (ss1 ss2 / e ss3)
  (setq ss3 (ssadd))
  (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss1))) 
     (if (ssmemb e ss2) (ssadd e ss3))
  )
  ss3
)

 

Edited by ymg3
One too many ssmemb remove, name of author typo
  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...