问题
I am trying to write a code using SCHEME that takes two arguments, for example '(2 1 3) & '(a b c) and gives a list '(b a c). My code is not working either recursive or iterative. Any help!!
(define project
(lambda (list1 list2 list3 n b index)
(define n (length(list1)))
(let ((i n))
(for-each (i)
(cond
((null? list1) (display "empty"))
(else
(define n (car list1))
(define index (- n 1))
(define b (list-ref list2 index))
(define list3 (cons list3 b))
(define list1 (cdr list1))
list3 ))))))
回答1:
(define (rearrange order l)
(cond ((number? order) (rearrange (list order) l))
((list? order) (map (lambda (num) (list-ref l (- num 1))) order))
(else 'bad-order)))
If you need order to be 'complex' (like '(1 (2 3) 4)
) then use this:
(define (listify thing)
(cond ((null? thing) '())
((pair? thing) (apply append (map listify thing)))
(else (list thing))))
> (listify 10)
(10)
> (listify '(1 (2 3) 4))
(1 2 3 4)
>
and then
(define (rearrange order l)
(map (lambda (num) (list-ref l (- num 1)))
(listify order)))
回答2:
Here's a version that handles arbitrarily-nested lists: first, a nested-map
that is like map
but handles nested lists:
(define (nested-map func tree)
(if (list? tree)
(map (lambda (x)
(nested-map func x))
tree)
(func tree)))
Then, we create a mapper to use with it (using list-ref
if the list is shorter than 16 elements, otherwise copying to a vector first for better scalability):
(define (rearrange indices lst)
(define mapper (if (< (length lst) 16)
(lambda (i)
(list-ref lst (- i 1)))
(let ((vec (list->vector lst)))
(lambda (i)
(vector-ref vec (- i 1))))))
(nested-map mapper indices))
Notice how, after the mapper is defined, the function is simply a single call to nested-map
. Easy! :-D
回答3:
First that came to mind:
(define (rearrange order symbols)
(define (element i list)
(if (= i 1)
(car list)
(element (- i 1) (cdr list))))
(define (iter order output)
(if (null? order)
output
(iter (cdr order)
(append output (list (element (car order) symbols))))))
(iter order '()))
Better solution:
(define (rearrange order symbols)
(define (nth-element i list)
(if (= i 1)
(car list)
(nth-element (- i 1) (cdr list))))
(map (lambda (x) (nth-element x symbols)) order))
回答4:
Here's a simple version for un-nested lists:
(define (arrange idx lst)
(map (lambda (i) (list-ref lst i)) idx))
(arrange '(1 0 2) '(a b c))
=> '(b a c)
If you need to use nested lists, flatten comes in handy:
(define (arrange idx lst)
(map (lambda (i) (list-ref lst i)) (flatten idx)))
(arrange '(1 (0 2)) '(a b c))
=> '(b a c)
Note that I use 0-based indexes, as is the custom in Scheme.
来源:https://stackoverflow.com/questions/17319737/rearrange-elements-in-a-list-using-scheme