Lisp enumerate iteration

I have a function that gets x (value) and xs (list) and removes all values ​​that are greater than x from the list. Well, this does not work, can you tell me why?

(defun biggerElems(x xs) (let ((xst)) (dolist (elem xs) (if (> x elem) (setf xst (remove elem xs)))) xst)) 
+4
source share
6 answers

I think this line is not correct:

 (setf xst (remove elem xs)))) 

The first argument to setf is the place followed by the value. It looks like you have it back (and xst either nil or uninitialized).

It might be easier for you to do this:

 (defun biggerElems (x xs) (remove-if (lambda (item) (> item x)) xs)) 
+5
source

The shortest AFAIK:

 (defun bigger-elements (x xs) (remove x xs :test #'<)) 

returns a new list, it removes all y elements from xs for which

 (< yx) 

or using the famous LOOP:

 (defun bigger-elements-2 (x xs) (loop for e in xs unless (< ex) collect e)) 
+4
source

It worked like this:

 (defun filterBig (x xs) (remove-if (lambda (item) (> item x)) xs)) 

What was the "#" for? He did not compile with it.

+1
source

If you want to do this in a Lisp way, you can use recursion to return a new list:

 (defun biggerElems (x xs) (cond ((null xs) NIL) ((< x (car xs)) (biggerElems x (cdr xs))) (t (cons (car xs) (biggerElems x (cdr xs)))))) 

@ Louis Oliveira

This decision should contrast with the one published in the question. If we needed to do something more complex, it would be important to justify a recursive approach to manipulating lists.

+1
source

@Ben: This is not a valid setf call - the problem is that it does not update xs.

i.e.: xst is installed in xs with the item removed, but xs is not updated. If the second item needs to be removed, xst will be the first in it.

you need to bind xst to xs and replace xs in the remove call with xst. Then this will remove all x elements more. i.e:

 (defun biggerElems(x xs) (let ((xst xs)) (dolist (elem xs) (when (> x elem) (setf xst (remove elem xst)))) xst)) 

It may be a little faster to install xst (copy-list xs) and then use delete instead of deleting (delete is destructive ... depending on your implementation, it may be faster than deleting. Since you call it several times, you can get better performance by copying the list once and destructively deleting it).

As an alternative:

 (defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own (loop for elem in xs when (<= x elem) collect elem)) 

Looking back at your original post, this is a bit confusing ... you say that you delete all elements larger than x, but your code looks like it is trying to delete all elements x more. The solutions I wrote return all elements larger than x (i.e.: delete all elements x greater than).

+1
source

What was the "#" for? This does not compile it.

typo. You usually refer to functions with #' (for example, (remove-if #'oddp list) ), but when I edited, I forgot to remove the "#".

0
source

Source: https://habr.com/ru/post/1276563/


All Articles