is there a way to replace the elements in a list?

Discussion of Common Lisp
Post Reply
yesimthetaxman
Posts: 10
Joined: Thu Jul 07, 2011 7:02 pm

is there a way to replace the elements in a list?

Post by yesimthetaxman » Tue Jul 12, 2011 10:55 pm

I don't actually mean destructively replace, I mean lets say you pass the list (a b c d e), I want to return the list (8 8 8 8 8)... so basically I want a list returned with the same number of elements but instead of the original items, it'd be an item of my choosing. I am able to do this using the replace function, but I am wondering if there is a way to implement this using something like mapcar or reduce.

Duke
Posts: 38
Joined: Sat Oct 17, 2009 10:40 pm
Contact:

Re: is there a way to replace the elements in a list?

Post by Duke » Tue Jul 12, 2011 11:10 pm

yesimthetaxman wrote:I don't actually mean destructively replace, I mean lets say you pass the list (a b c d e), I want to return the list (8 8 8 8 8)... so basically I want a list returned with the same number of elements but instead of the original items, it'd be an item of my choosing. I am able to do this using the replace function, but I am wondering if there is a way to implement this using something like mapcar or reduce.
Are you doing the L-99? (You probably should; you'd be able to answer this question yourself by #15 or so.)

One way to do it is with a recursive function. The form to do the rather silly thing you ask looks like this:

Code: Select all

CL-PIXIE> (defun dumb-replace (input-list substitution)
            (labels ((rec (lst acc)
                       (if (null lst)
                           acc
                           (rec (cdr lst) (cons substitution acc)))))
              (rec input-list nil)))
DUMB-REPLACE
CL-PIXIE> (dumb-replace (list 'a 'b 'c 'd) 'bork)
(BORK BORK BORK BORK)
...But it can change to suit a variety of problems, as you'll see if you're doing the L-99.
"If you want to improve, be content to be thought foolish and stupid." -Epictetus

marcoxa
Posts: 85
Joined: Thu Aug 14, 2008 6:31 pm

Re: is there a way to replace the elements in a list?

Post by marcoxa » Wed Jul 13, 2011 12:25 am

yesimthetaxman wrote:I don't actually mean destructively replace, I mean lets say you pass the list (a b c d e), I want to return the list (8 8 8 8 8)... so basically I want a list returned with the same number of elements but instead of the original items, it'd be an item of my choosing. I am able to do this using the replace function, but I am wondering if there is a way to implement this using something like mapcar or reduce.

Code: Select all

(defun transfomgrify (list &optional (e 42))
   (map 'list (constantly e) list))
Cheers
Marco Antoniotti

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: is there a way to replace the elements in a list?

Post by gugamilare » Wed Jul 13, 2011 10:34 am

@marcoxa and Duke: I think you guys misunderstood him, he wants to destructively replace the elements.

@yesimthetaxman: What you want is the function mapl:

Code: Select all

(defun my-replace (elt list)
  (mapl #'(lambda (sublist)
            (setf (car sublist) elt))
    list))
Note: I didn't test the code.

I X Code X 1
Posts: 59
Joined: Sun May 29, 2011 8:52 pm
Location: NY
Contact:

Re: is there a way to replace the elements in a list?

Post by I X Code X 1 » Wed Jul 13, 2011 10:55 am

gugamilare wrote:@marcoxa and Duke: I think you guys misunderstood him, he wants to destructively replace the elements.
yesimthetaxman wrote:I don't actually mean destructively replace.

I don't think he wants it to be destructively replaced.

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: is there a way to replace the elements in a list?

Post by gugamilare » Wed Jul 13, 2011 11:59 am

:oops:

marcoxa
Posts: 85
Joined: Thu Aug 14, 2008 6:31 pm

Re: is there a way to replace the elements in a list?

Post by marcoxa » Thu Jul 14, 2011 5:17 am

yesimthetaxman wrote:I don't actually mean destructively replace, I mean lets say you pass the list (a b c d e), I want to return the list (8 8 8 8 8)... so basically I want a list returned with the same number of elements but instead of the original items, it'd be an item of my choosing. I am able to do this using the replace function, but I am wondering if there is a way to implement this using something like mapcar or reduce.
I gave you the answer using MAP. The version with MAPCAR is

Code: Select all

(defun transmogrify (l &optional (x 42))
    (mapcar (constantly x) l))
A destructive version is

Code: Select all

(defun transmogrify/d (l &optional (x 42))
   (map-into l (constantly x) l))

Code: Select all

CL-USER 2 > (defvar ll (list 1 2 3 4))
LL

CL-USER 3 > (transmogrify/d ll)
(42 42 42 42)

CL-USER 4 > ll
(42 42 42 42)
Using the MAP version will hint you at generalizing the function so that it works with strings and vectors. :ugeek:

Cheers
Marco Antoniotti

yesimthetaxman
Posts: 10
Joined: Thu Jul 07, 2011 7:02 pm

Re: is there a way to replace the elements in a list?

Post by yesimthetaxman » Thu Jul 14, 2011 10:53 pm

thank youuuuuuuuu

Post Reply