Having a hard time with maps #123

Closed
opened 2 years ago by jaybonthius · 4 comments
jaybonthius commented 2 years ago (Migrated from github.com)

I have a list of hashes called hash_list.

'(
    #hasheq(
      (video . "path/to/example_0000.mp4")
    #hasheq(
      (video . "path/to/example_0001.mp4") 
)

I want to iterate through hash_list and generate a <video src="path/to/my/file.mp4" > for each "video" key.

<video src="path/to/example_0000.mp4"></video>
<video src="path/to/example_0001.mp4"></video>

Here's my attempt:

(define (video_env . text)
    `(video [[src ,text]])
)

(map (λ (hash)
    (video_env (hash-iterate-value hash 0)) )
    hash_list)

I'm getting a decode-elements: contract violation error, where it expects txexpr-elements?, and in the given, I see

... ((video ((src ("path/to/example_0000.mp4")))) (video ((src ("path/to/example_0001.mp4"))))) ...

I might be wrong, but I think decode-elements would be happy if it was given this:

... ((video ((src ("path/to/example_0000.mp4"))))) ((video ((src ("path/to/example_0001.mp4"))))) ...

Regardless, I'm not sure how to fix this. Would anyone mind pointing me in the right direction? Thanks!

I have a list of hashes called `hash_list`. ```racket '( #hasheq( (video . "path/to/example_0000.mp4") #hasheq( (video . "path/to/example_0001.mp4") ) ``` I want to iterate through `hash_list` and generate a `<video src="path/to/my/file.mp4" >` for each "video" key. ```html <video src="path/to/example_0000.mp4"></video> <video src="path/to/example_0001.mp4"></video> ``` Here's my attempt: ```racket (define (video_env . text) `(video [[src ,text]]) ) (map (λ (hash) (video_env (hash-iterate-value hash 0)) ) hash_list) ``` I'm getting a `decode-elements: contract violation` error, where it expects `txexpr-elements?`, and in the `given`, I see ```racket ... ((video ((src ("path/to/example_0000.mp4")))) (video ((src ("path/to/example_0001.mp4"))))) ... ``` I might be wrong, but I think `decode-elements` would be happy if it was given this: ```racket ... ((video ((src ("path/to/example_0000.mp4"))))) ((video ((src ("path/to/example_0001.mp4"))))) ... ``` Regardless, I'm not sure how to fix this. Would anyone mind pointing me in the right direction? Thanks!
sorawee commented 2 years ago (Migrated from github.com)

Hi!

I have a list of hashes called hash_list.

Note that the code that you wrote has missing parens, and is not a list of hashes. The list of hashes probably should be:

'(#hasheq((video . "path/to/example_0000.mp4"))
  #hasheq((video . "path/to/example_0001.mp4")))

Here's my attempt:

There are two possible mistakes here.

  1. Notice that in the output, you have (video [[src ("path/to/example_0000.mp4")]]). This doesn't make sense, because the attribute src should be associated with a string value, not a list of strings.

    The fix could be done by changing video-env to consume exactly one argument instead of making it consume variadic arguments. That is, you would need to make a definition like this instead:

    (define (video-env text)
      `(video [[src ,text]]))
    

    (Notice the absence of dot. Also, people usually use - instead of _ in names)

  2. Notice that in the output, you have ((video ...) (video ...)). This again doesn't make sense, because the body of the document should not be a list of elements. There are several ways to fix this. One possibility is:

    (apply @ (map .......))
    

So, your final code might look like this:

;; test.html.pm
#lang pollen

◊(define hash-list
  '(#hasheq((video . "path/to/example_0000.mp4"))
    #hasheq((video . "path/to/example_0001.mp4"))))

◊(define (video-env text)
  `(video [[src ,text]]))

◊(define (root . xs)
   (apply @ (map (λ (hash) (video-env (hash-ref hash 'video))) hash-list)))

which produces test.html after raco pollen render test.html.pm

<html>
  <head><meta charset="UTF-8"/></head>
  <body>
    <video src="path/to/example_0000.mp4"></video>
    <video src="path/to/example_0001.mp4"></video>
  </body>
</html>
Hi! > I have a list of hashes called `hash_list`. Note that the code that you wrote has missing parens, and is not a list of hashes. The list of hashes probably should be: ``` '(#hasheq((video . "path/to/example_0000.mp4")) #hasheq((video . "path/to/example_0001.mp4"))) ``` > Here's my attempt: There are two possible mistakes here. 1. Notice that in the output, you have `(video [[src ("path/to/example_0000.mp4")]])`. This doesn't make sense, because the attribute `src` should be associated with a string value, not a list of strings. The fix could be done by changing `video-env` to consume exactly one argument instead of making it consume variadic arguments. That is, you would need to make a definition like this instead: ``` (define (video-env text) `(video [[src ,text]])) ``` (Notice the absence of dot. Also, people usually use `-` instead of `_` in names) 2. Notice that in the output, you have `((video ...) (video ...))`. This again doesn't make sense, because the body of the document should not be a list of elements. There are several ways to fix this. One possibility is: ``` (apply @ (map .......)) ```` So, your final code might look like this: ``` ;; test.html.pm #lang pollen ◊(define hash-list '(#hasheq((video . "path/to/example_0000.mp4")) #hasheq((video . "path/to/example_0001.mp4")))) ◊(define (video-env text) `(video [[src ,text]])) ◊(define (root . xs) (apply @ (map (λ (hash) (video-env (hash-ref hash 'video))) hash-list))) ``` which produces `test.html` after `raco pollen render test.html.pm` ``` <html> <head><meta charset="UTF-8"/></head> <body> <video src="path/to/example_0000.mp4"></video> <video src="path/to/example_0001.mp4"></video> </body> </html> ```
jaybonthius commented 2 years ago (Migrated from github.com)

@sorawee That did the trick! Thank you so much for pointing out both errors and putting me on the right path. I'm beaming 😄

I dropped some parens in the hash lists when I wrote the question. Whoops!

@sorawee That did the trick! Thank you so much for pointing out both errors and putting me on the right path. I'm beaming 😄 I dropped some parens in the hash lists when I wrote the question. Whoops!
mbutterick commented 2 years ago (Migrated from github.com)

FWIW:

  • you can avoid using hash tables if you only have one value per record (and just use a flat list).
  • you can avoid defining a tag function if you just want the behavior of default-tag-function.
  • you can avoid using the splicing tag @ explicitly and instead use for/splice (which gathers the results of the iteration under a @ automatically)

So if you wished, you could simplify this example like so:

;; test2.html.pm
#lang pollen

◊(define videos
  '("path/to/example_0000.mp4"
    "path/to/example_0001.mp4"))

◊(for/splice ([v videos])
  (video #:src v))
FWIW: * you can avoid using hash tables if you only have one value per record (and just use a flat list). * you can avoid defining a tag function if you just want the behavior of `default-tag-function`. * you can avoid using the splicing tag `@` explicitly and instead use `for/splice` (which gathers the results of the iteration under a `@` automatically) So if you wished, you could simplify this example like so: ``` ;; test2.html.pm #lang pollen ◊(define videos '("path/to/example_0000.mp4" "path/to/example_0001.mp4")) ◊(for/splice ([v videos]) (video #:src v)) ```
jaybonthius commented 2 years ago (Migrated from github.com)

@mbutterick My hash table comes from parsing a .json with multiple values per record, which isn't obvious from my oversimplified example. Sorry about that. But your points on default-tag-function and for/splice are taken! And thanks for giving an example, I appreciate it.

@mbutterick My hash table comes from parsing a `.json` with multiple values per record, which isn't obvious from my oversimplified example. Sorry about that. But your points on `default-tag-function` and `for/splice` are taken! And thanks for giving an example, I appreciate it.
This repo is archived. You cannot comment on issues.
No Milestone
No project
No Assignees
1 Participants
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: mbutterick/pollen-users#123
Loading…
There is no content yet.