使用Scheme中的成员函数

时间:2010-10-26 19:20:50

标签: list scheme racket member

这是我的代码:

   (define p (read(open-input-file "starbucks4.sxml")))

(define get-artifacts
  (lambda (l)
   (member (list 'opm:artifact) l)))



  (get-artifacts p)

我被告知成员函数在整个列表中完全搜索。在.sxml文档中有一个复杂的列表,其中包含许多名为“opm:artifact”的元素,但是此方法返回#f且没有列表。

谁能看到我做错了什么?

.sxml文件示例:

      (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "Provide other Beverage")))
   "\n        ")
  "\n    ")
 "\n    "
 (opm:artifacts
  ()
  "\n        "
  (opm:artifact
   ((id "a1"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "order")))
   "\n        ")
  "\n        "
  (opm:artifact
   ((id "a2"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "cash")))
   "\n        ")
  "\n        "

我正在尝试查找所有opm:工件和相关数据(它的子列表)。

3 个答案:

答案 0 :(得分:2)

它会搜索整个列表,但不搜索子列表。

因此,如果您的列表实际上是嵌套列表,且(opm:artifact)仅位于其中一个子列表中,则member将无法找到它。

另请注意,您要查找列表(opm:artifact),而不是符号opm:artifact或包含opm:artifact的任何列表。

编辑:要搜索子列表,您可以执行以下操作:

(define (deep-search x lst)
  (if (empty? lst)
    #f
    (if (equal? x (car lst))
      #t
      (begin
        (if (list? (car lst))
          (let ((r (deep-search x (car lst))))
               (if r
                 r
                 (deep-search x (cdr lst))))
          (deep-search x (cdr lst)))))))

答案 1 :(得分:0)

我注意到的第一件事是你给出一个元素的列表作为member的第一个参数。会员的工作方式如下:

>>> (member 2 '(4 5 2 6 7))
(2 6 7)

您能否举例说明p的样子,以及您想要的结果?

答案 2 :(得分:0)

坚持下去,我可以让你的生活变得更轻松。根据您的“starbucks.sxml”文件名,看起来您已经在使用sxml racket包。如果是这样,那么你也可以使用该库的'sxpath'部分来大大简化你的代码:

#lang racket

(require (planet lizorkin/sxml:2:1/sxpath))

(define tree (file->value "/tmp/starbucks.sxml"))

(define artifact-filter (sxpath '(opm:artifact)))

(artifact-filter tree)

这将返回opm:artifact节点的列表(包括其中的所有内容)。例如,当我在你上面提供的片段上运行它时(加上一堆插入的开放式 - 它们没有平衡 - 我得到了这个:

Welcome to DrRacket, version 5.0.2.1--2010-10-27(41c084c/g) [3m].
Language: racket; memory limit: 512 MB.
'((opm:artifact
   ((id "a1"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "order")))
   "\n        ")
  (opm:artifact
   ((id "a2"))
   "\n            "
   (opm:account ((ref "detailedAccount")))
   "\n            "
   (opm:label ((value "cash")))
   "\n        "))

整个sxml包的文档真的很糟糕......也许“不存在”会是一个更好的词;公平地说,sxml人员有兴趣支持所有Scheme,而不仅仅是Racket,因此他们可以原谅不花大量时间以Racket格式编写文档,Scribble。