From: Philip Lijnzaad
Subject: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <u7hfffdhga.fsf@o2-3.ebi.ac.uk>
Dear all,

after some browsing in the HyperSpec, I couldn't find a function that yields,
as a list, the first N elts of the list passed as an argument, sort of the
opposites of [N]BUTLAST. I was thinking of something along the following lines:

  (defun ntruncate-list (list n)
    "destructive version of TRUNCATE-LIST"
    (cond ((zerop n) nil)
          ((>= n (length list)) list)
          (t (rplacd (nthcdr (1- n) list) nil) list)))
  
  (defun truncate-list (list n)
    "makes a truncated copy of LIST of at most length N. Only the structure of
  LIST is copied, not the elemements. Fails for circular or improper lists" 
    (ntruncate-list (append list nil) n))

Does such a function exist, and if so, what is it called, and if not, why not
(because it seems like a logical thing to have). Thanks for any info,

                                                                      Philip
-- 
Not getting what you want is sometimes a wonderful stroke of luck.
-----------------------------------------------------------------------------
Philip Lijnzaad, ········@ebi.ac.uk | European Bioinformatics Institute,rm A2-24
+44 (0)1223 49 4639                 | Wellcome Trust Genome Campus, Hinxton
+44 (0)1223 49 4468 (fax)           | Cambridgeshire CB10 1SD,  GREAT BRITAIN
PGP fingerprint: E1 03 BF 80 94 61 B6 FC  50 3D 1F 64 40 75 FB 53

From: Michael Kappert
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <38A40D95.5A39F4B7@iitb.fhg.de>
Philip Lijnzaad wrote:
> 
> Dear all,
> 
> after some browsing in the HyperSpec, I couldn't find a function that yields,
> as a list, the first N elts of the list passed as an argument, sort of the
> opposites of [N]BUTLAST. I was thinking of something along the following lines:

You need only to complement the index wrt. list length:

(defun ntruncate-list (list n)
   (nbutlast list (- (length list) n)))

Regards,
Michael.

-- 
Michael Kappert
Fraunhofer IITB
Fraunhoferstr. 1                                       Phone: +49(0)721/6091-477
D-76131 Karlsruhe, Germany                             EMail: ···@iitb.fhg.de
From: Philip Lijnzaad
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <u7ael7df0o.fsf@o2-3.ebi.ac.uk>
On Fri, 11 Feb 2000 14:24:37 +0100, 
"Michael" == Michael Kappert <···@iitb.fhg.de> writes:

Michael> Philip Lijnzaad wrote:

PL> I couldn't find a function that yields,
PL> as a list, the first N elts of the list passed as an argument, sort of the
PL> opposites of [N]BUTLAST. I was thinking of something along the following lines:

Michael> (defun ntruncate-list (list n)
Michael>   (nbutlast list (- (length list) n)))

Ah, of course, that's considerably easier. Still, is there a standard
function for doing this? 

Incidentally, I'm curious where the convention of an 'N' prefix for
destructive functions comes from. I suppose it all started with NCONC, but
there too, the N doesn't seem to be particularly mnemonic (non-consing?
nasty?)  Any veteran care to comment?

                                                                      Philip
-- 
Not getting what you want is sometimes a wonderful stroke of luck.
-----------------------------------------------------------------------------
Philip Lijnzaad, ········@ebi.ac.uk | European Bioinformatics Institute,rm A2-24
+44 (0)1223 49 4639                 | Wellcome Trust Genome Campus, Hinxton
+44 (0)1223 49 4468 (fax)           | Cambridgeshire CB10 1SD,  GREAT BRITAIN
PGP fingerprint: E1 03 BF 80 94 61 B6 FC  50 3D 1F 64 40 75 FB 53
From: Pierre R. Mai
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <87n1p77o1g.fsf@orion.dent.isdn.cs.tu-berlin.de>
Michael Kappert <···@iitb.fhg.de> writes:

> Philip Lijnzaad wrote:
> > 
> > Dear all,
> > 
> > after some browsing in the HyperSpec, I couldn't find a function
> > that yields, as a list, the first N elts of the list passed as an
> > argument, sort of the opposites of [N]BUTLAST. I was thinking of
> > something along the following lines:
> 
> You need only to complement the index wrt. list length:
> 
> (defun ntruncate-list (list n)
>    (nbutlast list (- (length list) n)))

If you are going to write an ntruncate function, then this approach is
needlessly sub-optimal, because it will have to traverse the whole
list first (to get length), before traversing the front part again to
modify/copy the head.  Philipp's version had the same problem.  The
following is my stab at writing ntruncate-list, which ignores out of
bounds indices and does the right thing w.r.t. to them (analogous to
nbutlast).

(defun ntruncate-list (list n)
  "Destructive version of truncate-list that returns (at most) the n
first elements of list as a list."
  (when (> n 0)
    (do ((i (1- n) (1- i))
	 (rest list (cdr rest)))
	((or (zerop i) (null (cdr rest)))
	 (setf (cdr rest) nil)
	 list))))

(defun truncate-list (list n)
  "Non-destructively returns (at most) the n first elements of list as
a list."
  (when (> n 0)
    (do* ((i (1- n) (1- i))
	  (rest (cdr list) (cdr rest))
	  (result (cons (car list) nil))
	  (result-rest result (cdr result-rest)))
	 ((or (zerop i) (null rest))
	  result)
      (setf (cdr result-rest) (cons (car rest) nil)))))

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Philip Lijnzaad
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <u77lgbd8vf.fsf@o2-3.ebi.ac.uk>
On 11 Feb 2000 16:32:27 +0100, 
"Pierre" == Pierre R Mai <····@acm.org> writes:

Pierre> needlessly sub-optimal, because it will have to traverse the whole
Pierre> list first (to get length), before traversing the front part again to
Pierre> modify/copy the head.  Philipp's version had the same problem.  

I thought of that, that's why I wrote

>> > argument, sort of the opposites of [N]BUTLAST. I was thinking of
>> > something along the following lines:

to get the idea across, not as a production quality code ... Thanks anyway
for the code!

                                                                      Philip
-- 
Not getting what you want is sometimes a wonderful stroke of luck.
-----------------------------------------------------------------------------
Philip Lijnzaad, ········@ebi.ac.uk | European Bioinformatics Institute,rm A2-24
+44 (0)1223 49 4639                 | Wellcome Trust Genome Campus, Hinxton
+44 (0)1223 49 4468 (fax)           | Cambridgeshire CB10 1SD,  GREAT BRITAIN
PGP fingerprint: E1 03 BF 80 94 61 B6 FC  50 3D 1F 64 40 75 FB 53
From: Andrew Cooke
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <881fjb$g94$1@nnrp1.deja.com>
In article <·················@iitb.fhg.de>,
  Michael Kappert <···@iitb.fhg.de> wrote:
> (defun ntruncate-list (list n)
>    (nbutlast list (- (length list) n)))

This is inefficient, isn't it?  It takes O((length list)) rather than
O(n).

(For a non-destructive version, loop with collect seems as good as
anything).

Andrew
http://www.andrewcooke.free-online.co.uk


Sent via Deja.com http://www.deja.com/
Before you buy.
From: Robert Munyer
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <88230s$ii5$1@eve.enteract.com>
In article <··············@o2-3.ebi.ac.uk>,
Philip Lijnzaad <········@ebi.ac.uk> wrote:

> after some browsing in the HyperSpec, I couldn't find a function
> that yields, as a list, the first N elts of the list passed as
> an argument, sort of the opposites of [N]BUTLAST.
  [...]
> Does such a function exist, and if so, what is it called, and if
> not, why not (because it seems like a logical thing to have).

For the non-destructive version, just use (SUBSEQ LIST 0 N).

For the destructive version, use (SETF (NTHCDR N LIST) NIL).

-- Robert Munyer <······@mcs.com>
From: Erik Naggum
Subject: Re: [N]TRUNCATE-LIST ?
Date: 
Message-ID: <3159291352590096@naggum.no>
* Philip Lijnzaad <········@ebi.ac.uk>
| after some browsing in the HyperSpec, I couldn't find a function that yields,
| as a list, the first N elts of the list passed as an argument, sort of the
| opposites of [N]BUTLAST.

  have you looked at SUBSEQ for the non-destructive version?  or a fairly
  plain SETF of NTHCDR for a destructive version?  if you have to check for
  the length, use NTHCDR, see if you get a cons cell, then SETF its CDR.
  there's absolutely _no_ need to check the length of the list, which,
  incidentally, may be circular, so use LIST-LENGTH instead of LENGTH if
  you think you really have to.

#:Erik