使用Scheme中的成员函数

发布于 2024-09-28 19:52:08 字数 948 浏览 3 评论 0原文

这是我的代码:

   (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:artifacts 和关联数据(它是子列表)。

This is my code:

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

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



  (get-artifacts p)

I was told that the member function searches completely throughout a list. In the .sxml document there is a complicated list that has many elements called "opm:artifact" however this method returns #f and no list.

Can anyone see what I am doing wrong?

Sample of .sxml file:

      (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        "

I'm trying to look for all the opm:artifacts and the associated data (it's sublists).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

以为你会在 2024-10-05 19:52:08

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

因此,如果您的列表实际上是一个嵌套列表,并且 (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)))))))

It does search through the whole list, but it doesn't search sublists.

So if your list is actually a nested list and the (opm:artifact) is only in one of its sublists, member won't find it.

Also note that you're looking for the list (opm:artifact), not the symbol opm:artifact or any list containing opm:artifact.

Edit: To search sublists you can do something like this:

(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)))))))
拍不死你 2024-10-05 19:52:08

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

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

您能给我们一个 p 的示例,以及您想要的结果吗?

The first thing I noticed is that you are giving a list of one element as your first argument to member. Member works like this:

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

Can you give us a sample of what p looks like, and what you want as a result?

忘羡 2024-10-05 19:52:08

坚持住,我可以让你的生活变得更轻松。根据您的“starbucks.sxml”文件名,您似乎已经在使用 sxmlracket 包。如果是这样,那么您还可以使用该库的“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 人员有兴趣支持所有方案,而不仅仅是 Racket,因此他们没有花大量时间以 Racket 格式(Scribble)编写文档当然可以被原谅。

Hang on, I can make your life a whole bunch easier. Based on your "starbucks.sxml" file name, it looks like you're already using the sxml racket package. If so, then you can also use the 'sxpath' part of that library to simplify your code drastically:

#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)

This returns a list of the opm:artifact nodes (including everything inside them). For instance, when I ran it on the fragment you provide above (plus a bunch of inserted open-parens--they weren't balanced--I got this:

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        "))

The documentation for the whole sxml package is really bad... perhaps "nonexistent" would be a better word; to be fair, though, the sxml folks are interested in supporting all Schemes, not just Racket, so they can certainly be forgiven for not spending lots of time writing documentation in the Racket format, Scribble.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文