Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Adding to Part of a List

  1. #1
    Design Visualization Moderator stusic's Avatar
    Join Date
    2004-10
    Location
    Denver, Colorado
    Posts
    1,515
    Login to Give a bone
    0

    Default Adding to Part of a List

    I'm iterating through a list that has machines arranged in groups ("A1", "A2", etc.). I'm trying to get a list that has the group ("A1") and how many machines are in each group. For example, there may be 8 machines in two groups: 1-5 in group "A1" and 6-8 in group "A2". I'm trying to get a list that has (("A1" 5) ("A2" 3)).

    Below is what I've got so far, but I can't figure out how to get it to add the quantity to the correct group as it's going through the foreach. Can someone point me in the right direction? Thanks for any insight, I'm stuck.

    Code:
    ;; "com" is a list of all the machines
    ;; "suc" is the group
    ;; "sgqty" is the number in each group
    ;; "rcksg" is the list I'm trying to create: (("A1" 5) ("A2" 3))
    (foreach com  (xins:massoc "compressor" lst)	   (cond
    		 	((= suc nil) ;; for the first machine
    			 	(and (setq suc (xins:assoc "suction_group" com)) ;; gets group name (eg, "A1")
    					 (setq sgqty (+ sgqty 1)) ;; counts the first machine
    
    					 (setq rcksg (list suc sgqty)))) ;; starts list
    			((= suc (xins:assoc "suction_group" com)) ;; sees if the group stays the same
    			 	(and (setq sgqty (+ sgqty 1)) ;; adds to count for the group
    					 (setq rcksg (subst sgqty ((member suc rcksg) sgqty))))) ;; adds to the list - this is the part that's messed up
    			((/= suc (xins:assoc "suction_group" com)) ;; different group
    			 	(and (setq suc (xins:assoc "suction_group" com)) ;; sets new group name
    					 (setq sgqty 1) ;; restarts count
    					 (setq rcksg (list (list rcksg) (list suc sgqty))))) ;; adds to the list
    	   )
    	 )
    Last edited by stusic; 2013-11-15 at 09:23 PM. Reason: I can't do maths.

  2. #2
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,713
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Code:
    (setq inventory '(("A1" "1" "2" "3" "4" "5") ("A2" "6" "7" "8")))
    
    (mapcar (function (lambda (x) (cons (car x) (length (cdr x)))))
            inventory
    )
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  3. #3
    Design Visualization Moderator stusic's Avatar
    Join Date
    2004-10
    Location
    Denver, Colorado
    Posts
    1,515
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Ah, but the list "inventory" isn't the same every time. There can be as many as 3 groups and as many as 10 machines, divided in any number of ways. So I've got to iterate through the big list ("com") and count all the machines in each, keeping track of which group they're in.

    Mach1: Group A1
    ("A1" 1)

    Mach2: Group A1
    ("A1" 2)

    Mach3: Group A1
    ("A1" 3)

    Mach4: Group A1
    ("A1" 4)

    Mach5: Group A1
    ("A1" 5)

    Mach6: Group A2
    (("A1" 5) ("A2" 1))

    Mach7: Group A2
    (("A1" 5) ("A2" 2))

    Mach8: Group A2
    (("A1" 5) ("A2" 3))

  4. #4
    Design Visualization Moderator stusic's Avatar
    Join Date
    2004-10
    Location
    Denver, Colorado
    Posts
    1,515
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Maybe just create a list for each group separately (rcksg1, rcksg2, rcksg3), then put them together at the end? I would think you guys would frown on such inefficiency...

  5. #5
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,713
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Quote Originally Posted by stusic View Post
    Ah, but the list "inventory" isn't the same every time. There can be as many as 3 groups and as many as 10 machines, divided in any number of ways. So I've got to iterate through the big list ("com") and count all the machines in each, keeping track of which group they're in.
    I cannot offer better advice, as I do not see where you're building your master list (com)... However, so long as the format is the same, it doesn't matter how many lists there are; that's the beauty of MAPCAR.

    Quick example:

    Code:
    (setq inventory '(("A1" "1" "2" "3" "4" "5")
                      ("A2" "6" "7" "8")
                      ("A3" "9" "10" "11" "12" "13")
                      ("A4" "14" "15" "16")
                      ("A5" "17" "18" "19" "20" "21")
                      ("A6" "22" "23" "24")
                     )
    )
    
    (mapcar (function (lambda (x) (cons (car x) (length (cdr x)))))
            inventory
    )
    ... Result from console:

    Code:
    _$ 
    
    (("A1" . 5) ("A2" . 3) ("A3" . 5) ("A4" . 3) ("A5" . 5) ("A6" . 3)) 
    _$
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  6. #6
    Design Visualization Moderator stusic's Avatar
    Join Date
    2004-10
    Location
    Denver, Colorado
    Posts
    1,515
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    This is an example of the com variable:

    Code:
    (("number" nil "1") ("suction_group" nil "A1") ("model" nil 
    "2DL3R78KL-TFC-C27") ("brand" nil "Copeland") ("type" nil "Reciprocating") 
    ("kw_part_number" nil "02P14022") ("suction_size" (("unit" . "in")) "1.375") 
    ("discharge_size" (("unit" . "in")) "0.875") ("power" (("unit" . "hp")) "5") 
    ("rla" (("unit" . "A")) "28.3333333333") ("lra" (("unit" . "A")) "169") 
    ("contactor" nil "C25DRF330B") ("circuit_breaker" nil "QC3050H") ("wire_size" 
    (("unit" . "awg")) "8") ("unloader" nil nil) ("suction_filter_shell" nil 
    (("model" nil "BTAS-311SV") ("kw_part_number" nil "96H46205"))) ("cch_current" 
    (("unit" . "A")) "0.480769230769") ("hcf_current" (("unit" . "A")) nil))
    (("number" nil "2") ("suction_group" nil "A1") ("model" nil 
    "3DB3R12ML-TFC-C27") ("brand" nil "Copeland") ("type" nil "Reciprocating") 
    ("kw_part_number" nil "02P14040") ("suction_size" (("unit" . "in")) "1.375") 
    ("discharge_size" (("unit" . "in")) "1.125") ("power" (("unit" . "hp")) "7.5") 
    ("rla" (("unit" . "A")) "39.1025641026") ("lra" (("unit" . "A")) "215") 
    ("contactor" nil "C25DRF340B") ("circuit_breaker" nil "QC3070H") ("wire_size" 
    (("unit" . "awg")) "8") ("unloader" nil nil) ("suction_filter_shell" nil 
    (("model" nil "BTAS-311SV") ("kw_part_number" nil "96H46205"))) ("cch_current" 
    (("unit" . "A")) "0.480769230769") ("hcf_current" (("unit" . "A")) nil))
    There is a "number" as the first item, but as much as I'd like to just use that, it's not reliable the same every time.

  7. #7
    Administrator Opie's Avatar
    Join Date
    2002-01
    Location
    jUSt Here (a lot)
    Posts
    9,089
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    You might try this.
    Code:
    (defun foo (lst value / inventory group)
      (foreach n lst
        (setq group (last (assoc value n)))
        (if	(not (assoc group inventory))
          (setq inventory (append inventory (list (cons group 1))))
          (setq inventory (subst
    		 (cons group (1+ (cdr (assoc group inventory))))
    		 (assoc group inventory)
    		 inventory
    	       )
          )
        )
      )
    )
    You would call it like this
    Code:
    (foo com "suction_group")
    If you have a technical question, please find the appropriate forum and ask it there.
    You will get a quicker response from your fellow AUGI members than if you sent it to me via a PM or email.
    jUSt

  8. #8
    Administrator BlackBox's Avatar
    Join Date
    2009-11
    Posts
    5,713
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    About a third faster....

    Code:
    (defun _foo (l v / i d g)
      ;; Example: (_foo com "suction_group")
      ;; Return: ("A1" . 2)
      (setq i 0)
      (foreach x l
        (if (and (or g (setq g (last (setq d (assoc v x)))))
                 (or d (assoc v x))
            )
          (setq i (1+ i))
        )
      )
      (if (< 0 i) (cons g i))
    )
    ... Quick speed test from console:

    Code:
    _$ (bench '(foo _foo) (list com "suction_group") 100000)
    
    FOO
    Elapsed: 1560
    Average: 0.0156
    
    _FOO
    Elapsed: 1185
    Average: 0.0119
    _$
    "How we think determines what we do, and what we do determines what we get."

    Sincpac C3D ~ Autodesk Exchange Apps

    Computer Specs:
    Dell Precision 3660, Core i9-12900K 5.2GHz, 64GB DDR5 RAM, PCIe 4.0 M.2 SSD (RAID 0), 16GB NVIDIA RTX A4000

  9. #9
    Past Vice President / AUGI Volunteer peter's Avatar
    Join Date
    2000-09
    Location
    Honolulu HI
    Posts
    1,104
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Maybe I am misunderstanding the question, but there are a few different ways to count the number of items in a list.

    Maybe sort them (acad_strlsort lstStrings)



    Code:
    ;I would create a sorted list of the members
    
    (duplicatesremove (list "A1" "A1" "A2" "A3" "A2" "A1")) returns '( "A1" "A2" "A3")
    
    ; and then count them
    (stringscount (list "A1" "A1" "A2" "A3" "A2" "A1")) returns '(("A1" 3) ("A2" 2) ("A3" 1))
    Code:
    
    (defun duplicatesremove (lstStrings / lstStrings2)
     (foreach strItem lstStrings
      (if (not (member strItem lstStrings2))
       (setq lstStrings2 (cons strItem lstStrings2))
      )
     )
     (if lstStrings2
      (acad_strlsort lstStrings2)
     )
    )
    
    (defun StringsCount (lstStrings / intCount ilstOfSublists)
     (foreach strItem (duplicateremove lstStrings)
      (setq intCount (apply '+ (mapcar '(lambda (X)(if (= X strItem) 1 0)) lstStrings)))
      (setq lstOfSublists (cons (list strItem intCount) lstOfSublists))
     )
     (reverse lstOfSublists)
    )
    or maybe do it this way.

    Code:
    ;I would create a list of sublists
    
    (stringsublists (list "A1" "A1" "A2" "A3" "A2" "A1")) returns '( ("A1" "A1" "A1") ("A2" "A2") ("A3") )
    
    ; and then count them
    (stringscount2 (list "A1" "A1" "A2" "A3" "A2" "A1")) returns '(("A1" 3) ("A2" 2) ("A3" 1))
    Code:
    (defun StringSublists (lstStrings / lstOfSublists strItem1 strItem2)
     (setq lstStrings   (reverse (acad_strlsort lstStrings))
           strItem1     (car lstStrings)
           lstStrings1  (list strItem1)
     )
     (foreach strItem2 (cdr lstStrings)
      (if (= strItem2 strItem1)
       (setq lstStrings1    (cons strItem2 lstStrings1))
       (setq lstOfSublists  (cons lstStrings1 lstOfSublists)
             lstStrings1    (list strItem2)
       )
      )
      (setq strItem1 strItem2)
     )
     (cons lstStrings1 lstOfSublists)
    ) 
    
    (defun StringsCount2 (lstStrings)
     (mapcar '(lambda (X)(list (car X)(length X))) (stringsublists lstStrings))
    )
    AutomateCAD

  10. #10
    Administrator Opie's Avatar
    Join Date
    2002-01
    Location
    jUSt Here (a lot)
    Posts
    9,089
    Login to Give a bone
    0

    Default Re: Adding to Part of a List

    Quote Originally Posted by BlackBox View Post
    About a third faster....
    I was wondering how long it was going to take before the topic of speed would come up.

    However, I do not think your code is returning the correct value. The snippet of data stusic posted above should be considered as a list, if I am not mistaken. If you copy one or more of those portions of the list to increase the size of the list and change the value of the "suction_group" assoc list to another value which is suggested above, your code will return the total count of the number of suction_group lists. It will not distinguish between different groups.

    Code:
    (_foo com "suction_group")
    ("A1" . 10)
    Code:
    (foo com "suction_group")
    (("A1" . 4) ("A2" . 4) ("A3" . 2))
    Furthermore, once you increase the number of lists within the com variable to around the number stusic also mentioned earlier, your code becomes slower when iterating through it the 100,000 times you displayed in your benchmark tests. See attached file for data I used for these tests.

    Code:
    (bench '(foo _foo) (list com "suction_group") 100000)
    
    FOO
    Elapsed: 4524
    Average: 0.0452
    
    _FOO
    Elapsed: 6271
    Average: 0.0627
    I highly doubt stusic plans on running through this snippet that many times when once through the routine would suffice. Therefore, I do not think the benchmark test is necessary.

    Stusic, if the attached data file is not correct, then this entire post is irrelevant. Hopefully, the code I posted earlier will help someone.
    Attached Files Attached Files
    If you have a technical question, please find the appropriate forum and ask it there.
    You will get a quicker response from your fellow AUGI members than if you sent it to me via a PM or email.
    jUSt

Page 1 of 2 12 LastLast

Similar Threads

  1. 2014: Adding part information to modeled part.
    By crullier in forum Inventor - General
    Replies: 5
    Last Post: 2015-01-30, 04:01 AM
  2. autocad 2012 adding unique part no for each visability
    By lesleys in forum Dynamic Blocks - Technical
    Replies: 4
    Last Post: 2012-05-21, 07:47 AM
  3. Adding Scale List to a drawing
    By harilalmn in forum AutoLISP
    Replies: 2
    Last Post: 2010-08-30, 12:00 PM
  4. Adding Part Number to Lookup Table
    By cdsuggs in forum Revit MEP - General
    Replies: 1
    Last Post: 2010-06-29, 06:14 PM
  5. Adding a value to position in a list
    By dkennard in forum AutoLISP
    Replies: 3
    Last Post: 2007-06-29, 01:03 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •