1

I struggling with a problem for hours now... I want to build a link with values from two sequences.

(doseq [item photoset-name] (prn item ))
(doseq [item-name photoset-id] (prn item-name ))

output:

"AlbumTitel2"
"test"
"AlbumTitel"
"album123"
"speciale"
"neues B5 Album"
"Album Nr 2"
"72157632764328569"
"72157632769231530"
"72157632769092584"
"72157632768156156"
"72157632762740183"
"72157632724688181"
"72157632760876608"

Now I want to build a link like this (for every id/name):

<a href="http://example.com?id=72157632764328569">AlbumTitel2</a>

And it should be a sequence or map... anything I can iterate though.

Does anyone have an idea how to archive this?

Thanks!

Nico
  • 1,071
  • 1
  • 23
  • 39

2 Answers2

2
(map #(str "<a href=\"http://example.com?id="
           %1
           "\">"
           %2
           "</a>") photoset-ids photoset-names)
Leon Grapenthin
  • 9,246
  • 24
  • 37
1

You could try using a map in one of two ways (I don't have Clojure handy at the moment so I can't verify):

(map #(prn "<a href=\"" %1 "\">" %2 "</a>") item item-name)

or

(doseq [pair (map vector item item-name)]
  (prn "<a href=\"" (first pair) "\">" (second pair) "</a>"))

EDIT: be careful using map; it's lazy so if you don't use the result returned by it then it might not actually be run!

This might also work:

(doseq [[url title] (map vector item item-name)]
  (prn "<a href=\"" url "\">" title "</a>"))

Combining items from multiple lists into pairs in a single list is commonly referred to as "zipping". The (map vector ...) I found in this answer

Community
  • 1
  • 1
paul
  • 1,655
  • 11
  • 23
  • 1
    Why would you want it to be run if you don't use the result? It's the whole point of laziness, isn't it? – Leon Grapenthin Aug 07 '13 at 22:05
  • @lgrapenthin you are correct; however, if you're unaware that `map` is lazy in Clojure and you try to do some sort of IO operation in it, using it as a general loop construct and not consuming the result, then you might be surprised, [as I was](http://stackoverflow.com/questions/12046515/listbox-jlist-wont-update-dynamically-from-custom-listmodel), when nothing happens. I just thought I'd mention this in case the OP didn't know. – paul Aug 07 '13 at 22:45
  • In the case that you linked to you were trying to invoke a function with side-effects using map. There, instead of using `doseq` as suggested in the answer you got, wrapping the call to map in a `dorun` usually performs better, as doseq should only be used when doing additional, `for`-like filtering/combining in the bindings. Btw., the map returned from the first line of your code will return a seq full of `nil`s. – Leon Grapenthin Aug 07 '13 at 23:14
  • Might be better to avoid doing the IO during the transformation (use str as per @lgrapenthin 's answer. – Alister Lee Aug 07 '13 at 23:20
  • 1
    @lgrapenthin: That's not true. `map` always makes all the intermediate allocations, while `doseq` does not. For that reason alone one would expect it to be faster. Then there's the fact that `dorun` is not chunked-seq-aware, whereas `doseq` is; `doseq` inlines the body in the expansion, while `map` uses the passed-in function in a higher order fashion; etc. In simple microbenchmarks using Criterium, with only one input collection and no processing of items beyond executing a body of expressions for side effects, `doseq` wins by fairly significant margins. – Michał Marczyk Aug 07 '13 at 23:26
  • 1
    Example microbenchmark: https://www.refheap.com/17369 (604 µs `doseq` vs. 987 µs `dorun map` when iterating over a range mutating a box at each step). I am of course only disagreeing with the assertion that `dorun map` should be preferred to `doseq` where both are applicable. Here `doseq` does not seem to be applicable in the first place, since the question asks for a seqable to be returned. – Michał Marczyk Aug 07 '13 at 23:33
  • 1
    Better microbenchmark (results: 624 µs vs. 977 µs): https://www.refheap.com/17370 – Michał Marczyk Aug 07 '13 at 23:43
  • I am surprised. I remember opposite results from my own benchmarks involving file IO. Well then I'll have to look into that again. – Leon Grapenthin Aug 08 '13 at 00:38
  • @lgrapenthin I was using `prn` in the iterated function since that's the function the OP was using in their example -- I seem to have missed the line where they wanted something iterable as a result. As you say, it should be using `str` instead so that the returned list isn't all `nil` values. – paul Aug 08 '13 at 01:13
  • @lgrapenthin Also, thanks for letting me know about `dorun`. I've been learning Clojure in a piecemeal fashion by reading docs for/finding functions when I need them, so I haven't had exposure to a lot of core's functions yet. – paul Aug 08 '13 at 01:15