From: Michael Akinde
Subject: Zip in ELisp
Date: 
Message-ID: <OwJV5.13847$zs.386864@twister.sunsite.auc.dk>
Is there a function corresponding to zip in common Lisp for elisp?

From: Hannah Schroeter
Subject: Re: Zip in ELisp
Date: 
Message-ID: <90dj1t$mco$1@c3po.schlund.de>
Hello!

In article <·····················@twister.sunsite.auc.dk>,
Michael Akinde <········@cs.auc.dk> wrote:
>Is there a function corresponding to zip in common Lisp for elisp?

What function "zip" in Common Lisp do you mean? I just checked
the Hyperspec and found none.

Kind regards,

Hannah.
From: Wolfhard Buß
Subject: Re: Zip in ELisp
Date: 
Message-ID: <m3lmtwgley.fsf@buss-14250.user.cis.dfn.de>
······@schlund.de (Hannah Schroeter) writes:

> What function "zip" in Common Lisp do you mean? I just checked
> the Hyperspec and found none.

Maybe

(defun zip (&rest list)
  (apply #'mapcar #'list list))

Any idea about an efficient unzip?
 ;-)

Regards,
Wolfhard.

-- 
"Das Auto hat keine Zukunft. Ich setze aufs Pferd."  Wilhelm II. (1859-1941)
From: Wolfhard Buß
Subject: Re: Zip in ELisp
Date: 
Message-ID: <m3aeacgh2f.fsf@buss-14250.user.cis.dfn.de>
I wrote:
> (defun zip (&rest list)
>   (apply #'mapcar #'list list))

Better:

(defun zip (list)
  (apply #'mapcar #'list list))

(zip '((Franz Lisp) (is a) (rich language)))

=> ((FRANZ IS RICH) (LISP A LANGUAGE))


Regards,
Wolfhard.

-- 
"Das Auto hat keine Zukunft. Ich setze aufs Pferd."  Wilhelm II. (1859-1941)
From: Kent M Pitman
Subject: Re: Zip in ELisp
Date: 
Message-ID: <sfwhf4j7rh6.fsf@world.std.com>
·····@gmx.net (Wolfhard Bu�) writes:

> ······@schlund.de (Hannah Schroeter) writes:
> 
> > What function "zip" in Common Lisp do you mean? I just checked
> > the Hyperspec and found none.
> 
> Maybe
> 
> (defun zip (&rest list)
>   (apply #'mapcar #'list list))
> 
> Any idea about an efficient unzip? ;-)

Efficient?  Well, something like this isn't too bad:

 (DEFUN UNZIP (LISTS)
   ;; this first call to COPY-LIST isn't needed if 
   ;; you don't mind destroying your arg
   (LET ((TEMP (COPY-LIST LISTS))) 
     (LOOP WHILE (EVERY #'IDENTITY TEMP)
           COLLECT (MAPLIST #'(LAMBDA (X) (POP (CAR X))) TEMP))))

There's some issue about what to do as the end test if the lists are not
of identical length.  It also works to use SOME instead of EVERY here,
depending on whether you want to pad short lists with NIL's or truncate
long lists.

Modulo the individual implementation's ability to optimize MAPLIST, and
the optional COPY-LIST issue, the following is uglier but probably closer
to optimal in speed because it coroutines the accumulation pass with
the end-test.

 (DEFUN UNZIP! (LISTS)
   (LET ((RESULT '()))
     (LOOP (LET ((ITEM (MAPLIST #'(LAMBDA (X)
				    (IF (CAR X) (POP (CAR X)) (RETURN)))
				LISTS)))
	     (PUSH ITEM RESULT)))
     (NREVERSE RESULT)))

I would usually opt for the "inefficient" version because it's so much more
readable unless I knew this speed issue was a bottleneck.  This at least 
does no gratuitous consing...

[I only did very light testing on these, so watch out.]
From: Wolfhard Buß
Subject: Re: Zip in ELisp
Date: 
Message-ID: <m3aea9odqk.fsf@buss-14250.user.cis.dfn.de>
Kent M Pitman <······@world.std.com> writes:

> ·····@gmx.net (Wolfhard Bu�) writes:
> 
> > ······@schlund.de (Hannah Schroeter) writes:
> > 
> > > What function "zip" in Common Lisp do you mean? I just checked
> > > the Hyperspec and found none.
> > 
> > Maybe
> > 
> > (defun zip (&rest list)
> >   (apply #'mapcar #'list list))
> > 
> > Any idea about an efficient unzip? ;-)
> 
> Efficient?  Well, something like this isn't too bad:
> 
>  (DEFUN UNZIP (LISTS)
>    ;; this first call to COPY-LIST isn't needed if 
>    ;; you don't mind destroying your arg
>    (LET ((TEMP (COPY-LIST LISTS))) 
>      (LOOP WHILE (EVERY #'IDENTITY TEMP)
>            COLLECT (MAPLIST #'(LAMBDA (X) (POP (CAR X))) TEMP))))
> 
> There's some issue about what to do as the end test if the lists are not
> of identical length.  It also works to use SOME instead of EVERY here,
> depending on whether you want to pad short lists with NIL's or truncate
> long lists.

A primitive less flexible version of zip and unzip:

 (defun zip (lists)
   (apply #'mapcar #'list lists))

 (defun unzip (lists)
   (apply #'mapcar #'list lists))

Regards,
Wolfhard.

-- 
"Das Auto hat keine Zukunft. Ich setze aufs Pferd."  Wilhelm II. (1859-1941)
From: Kent M Pitman
Subject: Re: Zip in ELisp
Date: 
Message-ID: <sfwr93lva9w.fsf@world.std.com>
·····@gmx.net (Wolfhard Bu�) writes:

> Kent M Pitman <······@world.std.com> writes:
> 
> >  (DEFUN UNZIP (LISTS)
> >    ;; this first call to COPY-LIST isn't needed if 
> >    ;; you don't mind destroying your arg
> >    (LET ((TEMP (COPY-LIST LISTS))) 
> >      (LOOP WHILE (EVERY #'IDENTITY TEMP)
> >            COLLECT (MAPLIST #'(LAMBDA (X) (POP (CAR X))) TEMP))))
> > 
> > There's some issue about what to do as the end test if the lists are not
> > of identical length.  It also works to use SOME instead of EVERY here,
> > depending on whether you want to pad short lists with NIL's or truncate
> > long lists.
>
> A primitive less flexible version of zip and unzip:
> 
>  (defun zip (lists)
>    (apply #'mapcar #'list lists))
> 
>  (defun unzip (lists)
>    (apply #'mapcar #'list lists))

Yes, but this destroys my only-about-every-five-years opportunity to
use MAPLIST for something.  In my experience, that operator hardly
gets used.  (Well, not as rarely as MAPCON, which I think I last used
when trying to come up for an example of it to put in the ANSI CL spec.)

Anyway, it's pretty funny that zip is its own inverse.  I completely
missed that when looking at this before.  Thanks for following up
with this extra info.
From: Nicolas Neuss
Subject: Re: Zip in ELisp
Date: 
Message-ID: <wssno0noxm.fsf@ortler.iwr.uni-heidelberg.de>
Kent M Pitman <······@world.std.com> writes:

> > A primitive less flexible version of zip and unzip:
> > 
> >  (defun zip (lists)
> >    (apply #'mapcar #'list lists))
> > 
> >  (defun unzip (lists)
> >    (apply #'mapcar #'list lists))
> 
> Anyway, it's pretty funny that zip is its own inverse.  I completely
> missed that when looking at this before.  Thanks for following up
> with this extra info.

On the other hand it is quite obvous, if you consider this as matrix
transposition with the matrix being given as a list of row-lists.

Nicolas.