T
Thomas
Guest
what is the most effectiant way?
Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Jimkawrote:
the easiest way to do this is to build the list in the other
order. ask yourself why is the list in the order it is in, and
can it be built in the other order.
for example if you use push to add elements to a list
then you can use pop to pop them off. this is
very fast and memory efficient.
but in general to remove any element from a list with the
remove function.
x = (list 1 2 3 4 5 6 7)
now x has value (1 2 3 4 5 6 7)
if you want to remove 4 from x
(remove 4 x)
and x has value (1 2 3 5 6 7)
-jim
How did the element you want to remove get at the end of the list?
Why is it the last element you need to remove rather than the 13th for
example? Sometimes there are very good reasons for operating
on the last element, however it normally means you built the list
in the wrong order to begin with, or that you should be using a
different type of data structure than a list.
How did the element get to the end of the list anyway?
Why don't you already know its value without having to use
car(last(...))?
Here's a version that does it destructively, so avoids the need toyes you are right, as i said there are certainly very good reasons for
wanting
to do this. However, in my experience it is also quite often that
the programmer is going about the problem wrong, and it is really
much simpler. I.e., if his program put the element at the end of
the list, then simply avoid putting it there and the problem does
not arrise. If he knows what the last element is, he can remove it
with remove (assuming it only appears at the end and not also
somewhere in the middle).
list = ( 1 2 3 1 2 3 1 2 3 1 2 3 1 2)
(remove 2 list) will return ( 1 3 1 3 1 3 1 3 1)
which is probably not what you want.
If you really want to remove the last element of a list without
knowing what it is try this:
(defun remove_last (list)
(let ((new (list nil))) ; allocate a seed for tconc
(foreach map sublist list ; iterate over the cons cells
(when (cdr sublist) ; unless we are at the end of
the list
(tconc new (car sublist)))) ; efficiently append an element
(car new))) ; return the new list
this will also work, but consumes
a lot of memory for large lists.
(defun remove_last (list)
(reverse (cdr (reverse list))))
forJimkawrote:
yes you are right, as i said there are certainly very good reasons
wanting
to do this. However, in my experience it is also quite often that
the programmer is going about the problem wrong, and it is really
much simpler. I.e., if his program put the element at the end of
the list, then simply avoid putting it there and the problem does
not arrise. If he knows what the last element is, he can remove it
with remove (assuming it only appears at the end and not also
somewhere in the middle).
list = ( 1 2 3 1 2 3 1 2 3 1 2 3 1 2)
(remove 2 list) will return ( 1 3 1 3 1 3 1 3 1)
which is probably not what you want.
If you really want to remove the last element of a list without
knowing what it is try this:
(defun remove_last (list)
(let ((new (list nil))) ; allocate a seed for
tconc
(foreach map sublist list ; iterate over the cons
cells
(when (cdr sublist) ; unless we are at the end
of
the list
(tconc new (car sublist)))) ; efficiently append an
element
(car new))) ; return the new list
this will also work, but consumes
a lot of memory for large lists.
(defun remove_last (list)
(reverse (cdr (reverse list))))
try it withWhat about
x = list( 1 2 3 4 5 6 7 )
remove( length( x ) x )
Whilst the above traverses the list just once, it has repeatedHere's a version that does it destructively, so avoids the need to
create a new list (but has the side effect of modifying the list in place,
so be warned):
(defun abRemoveLast (list)
(when (cdr list)
(foreach map sublist list
(unless (cddr sublist) (rplacd sublist nil))
)
)
)
Andrew.
Bernd Fischer > wrote:
What about
x = list( 1 2 3 4 5 6 7 )
remove( length( x ) x )
try it with
x=list( a b c d )
I just profiled this:another way to do it would work if you can always remember
how long the list is. Since you are removing items in pairs,
first and last, the length decreases by 2 each time.
you can use (rplacd (nthcdr N the_list))
(nthcdr 0 ...) returns the list
(nthcdr 1 ...) returns the list after the first element
(nthcdr 2 ...) returns the list after the 2nd element
(sorry, i might be off by 1 in the index....)
so to remove everything after the Nth element (zero
based) you can use (rplacd (nthcdr N the_list))
I certainly attempt to avoid dealing with the last element of the list
in my program,
but the list is symmetric and the status of the first element is same
as the last one, and so on.
All the elements is useful at first, then the first and last one need
to be deleted.
I know that deleting one element of a list in other programming
language is an trivial operation and a single traversal is enough.
I put forward the question since I am afraid of not reading the
documents of SKILL thoroughly.
It has nothing to do with the data structure and code style of my
program.
Jimkawrote:
yes you are right, as i said there are certainly very good reasons
for
wanting
to do this. However, in my experience it is also quite often that
the programmer is going about the problem wrong, and it is really
much simpler. I.e., if his program put the element at the end of
the list, then simply avoid putting it there and the problem does
not arrise. If he knows what the last element is, he can remove it
with remove (assuming it only appears at the end and not also
somewhere in the middle).
list = ( 1 2 3 1 2 3 1 2 3 1 2 3 1 2)
(remove 2 list) will return ( 1 3 1 3 1 3 1 3 1)
which is probably not what you want.
If you really want to remove the last element of a list without
knowing what it is try this:
(defun remove_last (list)
(let ((new (list nil))) ; allocate a seed for
tconc
(foreach map sublist list ; iterate over the cons
cells
(when (cdr sublist) ; unless we are at the end
of
the list
(tconc new (car sublist)))) ; efficiently append an
element
(car new))) ; return the new list
this will also work, but consumes
a lot of memory for large lists.
(defun remove_last (list)
(reverse (cdr (reverse list))))