我怎样才能从过滤器图中获得一个解决方案?

时间:2014-05-07 17:28:22

标签: scheme

(filter-map (lambda (x y) (and (eq? x z)   y) ) list1 list2 ) 
方案中的

,我有两个列表list1list2,如果list1的任何元素等于z,我想返回对应list2元素。我知道list1上只有一个元素等于z。

我的代码正在运行,但我得到的结果是'(bla),但我只希望得到bla如何删除此括号的结果?

3 个答案:

答案 0 :(得分:2)

您可以使用car检索输出列表中的第一个元素,但我认为filter-map是最佳选择 - 毕竟您对此不感兴趣filter-map返回的结果列表,仅在一个元素中 - 这是不可避免的,即使它是空的,也会返回 列表。基本上,您需要在关联列表中查找值。试试这个:

(cdr (assq 'z (map cons list1 list2)))
=> 'bla

说明:

  • (map cons list1 list2)构建一个关联列表,其中list1中的元素是键,list2中的元素是值
  • assq查找以'z为键的键值对(使用eq?进行比较),并返回该对
  • cdr返回该对的值部分

或者,您可以检查您的解释器是否有可用的哈希表实现(如果您必须有效地执行多个搜索,则非常有用),例如在Racket中:

(hash-ref (make-hasheq (map cons list1 list2)) 'z)
=> 'bla

说明:

  • (map cons list1 list2)构建一个关联列表,其中list1中的元素是键,list2中的元素是值
  • make-hasheq使用关联列表创建新的哈希表,并在找到给定键的值时使用eq?
  • hash-ref返回与密钥'z
  • 对应的值

请注意,如果list1中的密钥没有出现,我们尝试获取值时,上述两个选项都会引发错误,如果需要,您必须决定如何处理此情况出现;例如,我们可以返回#f

(let ((pair (assq 'z (map cons list1 list2))))
  (and pair (cdr pair)))

(hash-ref (make-hasheq (map cons list1 list2)) 'z
          (const #f))

答案 1 :(得分:0)

天真的方法是在结果上调用car,因为car返回列表的第一个元素。但如果没有元素匹配,那将导致错误 - 您的函数将返回一个空列表,car将失败。

某些语言(即Haskell)实现option type。选项类型为空或仅包含一个值。它有点类似于可以包含不超过一个值的列表。您可以为scheme实现一个并将其用作返回类型。

另一种方法是返回列表'第一个元素,如果没有找到结果,则为#f(false)。这种方法基于Scheme是动态语言的事实。

答案 2 :(得分:0)

虽然filter-map很好并且功能正常,但迭代答案可能是更简单(阅读:可理解)的方法来解决这个问题。

#lang racket
(define list1 '(a b z d))
(define list1a '(a b c d)) ; doesn't have 'z in it
(define list2 '(1 2 3 4))
(define (find-matching-pair lst1 lst2)
  (let loop ((l1 lst1)
             (l2 lst2))
    (cond ((null? l1) #f) ; didn't find it
          ((eqv? (car l1) 'z) (car l2)) ; this ASSUMES l2 is not shorter than l1
          (else (loop (cdr l1) (cdr l2))))))
(find-matching-pair list1 list2) ; => 3
(find-matching-pair list1a list2) ; => #f