Jump to content

convert list with mapcar, lambda...


robierzo

Recommended Posts

  • Replies 23
  • Created
  • Last Reply

Top Posters In This Topic

  • robierzo

    9

  • Lee Mac

    8

  • marko_ribar

    4

  • David Bethel

    1

(defun every2nd ( lst )
 (vl-remove nil (mapcar '(lambda ( a ) (if (eq (rem (vl-position a lst) 2) 0) a)) lst))
)

(defun groupby2 ( lst )
 (mapcar '(lambda ( a b ) (list a b)) (every2nd lst) (every2nd (cdr lst)))
)

(groupby2 '(51 41 83 10 60 32 46 84))

 

M.R.

Link to comment
Share on other sites

Maybe :

 

 

 

[b][color=BLACK]([/color][/b]setq lst '[b][color=FUCHSIA]([/color][/b]51 41 83 10 60 32 46 84[b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b]

[b][color=BLACK]([/color][/b]defun lby2 [b][color=FUCHSIA]([/color][/b]l / tmp[b][color=FUCHSIA])[/color][/b]
 [b][color=FUCHSIA]([/color][/b]while l
   [b][color=NAVY]([/color][/b]setq tmp [b][color=MAROON]([/color][/b]cons [b][color=GREEN]([/color][/b]list [b][color=BLUE]([/color][/b]nth 0 l[b][color=BLUE])[/color][/b] [b][color=BLUE]([/color][/b]nth 1 l[b][color=BLUE])[/color][/b][b][color=GREEN])[/color][/b] tmp[b][color=MAROON])[/color][/b]
           l [b][color=MAROON]([/color][/b]cdr l[b][color=MAROON])[/color][/b]
           l [b][color=MAROON]([/color][/b]cdr l[b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b]
[b][color=FUCHSIA]([/color][/b]reverse tmp[b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b]

 

 

I would recommend doing some basic error checking for these types of routine

 

ie is the length of the list an even number.

 

-David

Link to comment
Share on other sites

(defun every2nd ( lst )
 (vl-remove nil (mapcar '(lambda ( a ) (if (eq (rem (vl-position a lst) 2) 0) a)) lst))
)

(defun groupby2 ( lst )
 (mapcar '(lambda ( a b ) (list a b)) (every2nd lst) (every2nd (cdr lst)))
)

(groupby2 '(51 41 83 10 60 32 46 84))

 

Be careful with duplicates...

_$ (every2nd '(1 2 3 1 2 3))
(1 3 1 3)

For your method, consider perhaps:

(defun f ( l / i )
   (setq i -1)
   (vl-remove-if '(lambda ( x ) (= 1 (rem (setq i (1+ i)) 2))) l)
)
(defun g2 ( l ) (mapcar 'list (f l) (f (cdr l))))

_$ (g2 '(1 2 3 1 2 3))
((1 2) (3 1) (2 3))

Link to comment
Share on other sites

Three alternatives

1 - recursive - similar to Lee (see l2p function)

 

2 - using foreach

(defun ph1:l2p (l / s r)
 (foreach x l
   (if s
      (setq r (cons (list s x) r)
            s nil
      )
      (setq s x)
   )
 )
 (reverse r)
)

3 - using repeat

(defun ph2:l2p (l / r)
 (repeat (/ (length l) 2)
   (setq r (append r (list (list (car l) (cadr l))))
         l (cddr l)
   )
 )
 r
)

Link to comment
Share on other sites

I thought it would be easier with mapcar and lambda.

 

Note that not all tasks are best solved using mapcar.

For this particular example, the items in the list need to be processed in pairs, hence mapcar is not best suited for the task since it will process every item in a list consecutively, meaning that you must first manipulate the list before passing it to mapcar. This extra work to manipulate the list is very inefficient where other methods could process the list directly.

 

The mapcar function is just one tool in your AutoLISP toolbox, from which you should choose the best tool for the job. Restricting yourself to solely using mapcar for every task would be like building a house with just a hammer...

Link to comment
Share on other sites

Be careful with duplicates...

_$ (every2nd '(1 2 3 1 2 3))
(1 3 1 3)

 

You're right as always Lee... So my first code :

(defun every2nd ( lst / x )
 (setq x -1)
 (vl-remove nil (mapcar '(lambda ( a ) (if (eq (rem (setq x (1+ x)) 2) 0) a)) lst))
)

(defun groupby2 ( lst )
 (mapcar '(lambda ( a b ) (list a b)) (every2nd lst) (every2nd (cdr lst)))
)

(groupby2 '(1 2 3 1 2 3))

Link to comment
Share on other sites

I can not see post # 11 and following.

I get this message:

 



[b]Forbidden[/b]

You don't have permission to access /forum/showthread.php on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.



Link to comment
Share on other sites

I can not see post # 11 and following.

I get this message:

 



[b]Forbidden[/b]

You don't have permission to access /forum/showthread.php on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

 

This is because you have used "...." in your thread title.

Link to comment
Share on other sites

So, is this the shortest ?

 

(defun every2nd ( lst / x )
 (setq x -1)
 (vl-remove-if-not '(lambda ( a ) (eq (rem (setq x (1+ x)) 2) 0)) lst)
)

(defun groupby2 ( lst )
 (mapcar 'list (every2nd lst) (every2nd (cdr lst)))
)

(groupby2 '(1 2 3 1 2 3))

Link to comment
Share on other sites

So, is this the shortest?

 

If you were to remain using the vl-remove-if-not function (or vl-remove-if function, as per my earlier post), then those arrangements would most likely be the shortest.

 

Shorter code could obviously be obtained by using alternative methods to generate each list supplied to mapcar:

(defun f ( l ) (if l (cons (car l) (f (cddr l)))))
(defun g ( l ) (mapcar 'list (f l) (f (cdr l))))

...Or of course by abandoning mapcar as stated and demonstrated in my earlier posts.

Link to comment
Share on other sites

;; Group by number by M.R. ;;

(defun gn ( l n / f g k q ) 
 (setq k n q l)
 (defun f ( l n ) (if (and l (> n 0)) (cons (car l) (f (setq q (setq l (cdr l))) (setq n (1- n))))))
 (defun g ( l n ) (if q (cons (f q k) (g q k))))
 (g q k)  
)

(gn '(11 21 31 12 22 32) 2)

 

M.R.

Link to comment
Share on other sites

;; Group by number by M.R. ;;

(defun gn ( l n / f g k q ) 
 (setq k n q l)
 (defun f ( l n ) (if (and l (> n 0)) (cons (car l) (f (setq q (setq l (cdr l))) (setq n (1- n))))))
 (defun g ( l n ) (if q (cons (f q k) (g q k))))
 (g q k)  
)

(gn '(11 21 31 12 22 32) 2)

 

Since you are calling the function f recursively, the use of setq (as noted the following expression) is unnecessary, as the values of the symbols l and n are passed as arguments to the f function.

 

(f (setq q [highlight](setq[/highlight] l (cdr l))) [highlight](setq[/highlight] n (1- n)))

Also, by renaming the parameters of the f function, you could remove the need for the extra 'state' variables k & q, e.g.:

 

(defun gn ( l n / f g )
   (defun f ( a b )
       (if (and a (< 0 b))
           (cons (car a) (f (setq l (cdr a)) (1- b)))
       )
   )
   (defun g ( l n ) (if l (cons (f l n) (g l n))))
   (g l n)
)

However, note further that the function g is also superfluous since it is identical to the function in which it is defined:

 

(defun gn ( l n / f )
   (defun f ( a b )
       (if (and a (< 0 b))
           (cons (car a) (f (setq l (cdr a)) (1- b)))
       )
   )
   (if l (cons (f l n) (gn l n)))
)

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...