How do I subtract 1 from the second element of the list (3 6)
?
(setq x '(3 6))
(- (nth 1 x) 1)
The above quote does the math but does not return a modified list.
Using the built-in cl-lib
package, you can write the following:
(eval-when-compile
(require 'cl-lib))
(cl-decf (nth 1 x))
Alternatively, in vanilla Elisp:
(setf (nth 1 x) (1- (nth 1 x)))
Be careful, though, to avoid modifying quoted constant lists such as '(3 6)
in-place, as doing so modifies the constant globally and may cause the code to behave differently in separate runs.
Instead, make sure to operate on a new list each time, e.g. via:
(setq x (list 3 6))
cl-lib
(not the obsolete cl
) and vanilla Elisp, and added a warning against destructive modifications. If you or the author are opposed to these additions, you are free to revert my suggestions. Writing a separate answer for these extensions would be redundant and off-topic.
cl.el
is not obsolete. Some features of that library are obsolete. See CL: Obsolete Features.
cl.el
is not officially obsolete, but its use is discouraged in favour of cl-lib.el
where practical. See (cl) Organization
.
Just tinkering, you can use car
and cdr
too. I'm sure someone will comment on whether this is good or bad.
(let ((v 99) (p 3) (l (list 1 2 3 4)))
(setcar (nthcdr p l) (+ (car (nthcdr p l)) v))
l)
;; => (1 2 3 103)
-
is a pure arithmetic function which accepts numbers and returns a number. It knows nothing about where the arguments came from and does not modify any stored data. If you care about the result of the arithmetic operation then you should store it back in the list, e.g. using the convenient macros listed in the answer(s) below. Be careful, though, not to destructively modify quoted constant lists such as'(3 6)
in-place; make a copy of the list usingcopy-sequence
first or allocate a new one using(list 3 6)
instead.