clojure for 循环,将值存储在集合或映射中

发布于 2024-12-07 12:57:29 字数 248 浏览 0 评论 0原文

这个问题困扰我有一段时间了 我们应该如何在 for 循环中将值存储在集合或映射中?

(let [s #{}]
     (for [ i (range 10)
            j (range 10) ]
      (into s [i j])))

我知道这行不通,但我想要一个与此类似的功能,其中该集合最终将包含 [0 0] [0 1]...[0 9] [1 0]...[9 9]

谢谢

This one has been bothering me for a while now,
How should we store a value in a set or map in a for loop?

(let [s #{}]
     (for [ i (range 10)
            j (range 10) ]
      (into s [i j])))

i know this will not work, but i want a functionality similar to this , where the set will finally contain [0 0] [0 1]...[0 9] [1 0]...[9 9]

Thanks

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

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

发布评论

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

评论(5

浅语花开 2024-12-14 12:57:29

如果我正确理解你的问题,你需要把你的表达从里到外:

(let [s #{}]
  (into s (for [i (range 10) 
                j (range 10)] 
            [i j])))

这里要意识到的是 for 返回一个值(惰性序列),与 Java 和 C 等命令式语言中的 for 循环不同。

If I understand your question correctly you need to turn your expression inside-out:

(let [s #{}]
  (into s (for [i (range 10) 
                j (range 10)] 
            [i j])))

The thing to realize here is that for returns a value (a lazy sequence) unlike for-loops in more imperative languages like Java and C.

轻许诺言 2024-12-14 12:57:29

这是你想要的吗?

(into #{} (for [i (range 10) j (range 10)]
  [i j]))
;-> #{[2 1] [3 2] [4 3] [5 4] [6 5] [7 6] [8 7] [9 8] [1 0]
;     [2 2] [3 3] [4 4] [5 5] [6 6]...

如果您只想将列表作为一组:

(set (for [i (range 10) j (range 10)]
  [i j]))    

您最终会得到一组对。

Is this what you want?

(into #{} (for [i (range 10) j (range 10)]
  [i j]))
;-> #{[2 1] [3 2] [4 3] [5 4] [6 5] [7 6] [8 7] [9 8] [1 0]
;     [2 2] [3 3] [4 4] [5 5] [6 6]...

And if you just want the list as a set:

(set (for [i (range 10) j (range 10)]
  [i j]))    

You will end up with a set of pairs.

小嗷兮 2024-12-14 12:57:29

通常当您想要从 seq 上的“重复”广义操作返回一个集合、映射或其他不是 seq 的“单值”时,请使用 reduceloop/recur更惯用/直接,并且for总是返回一个seq(而不是一个集合或映射)。

(reduce conj #{} (for [i (range 10) j (range 10)] [i j]))

请注意,(for ..) 此处仅用于生成一个包含所有要编译到单个结果中的值的 seq。或者,例如:

(reduce + 0 (range 100))
=> 4950

Generally when you want to return a set or a map or other 'single value' that isn't a seq from a 'repeated' generalized operation on a seq, using reduce is more idiomatic/straightforward than loop/recur, and for always returns a seq (not a set or map).

(reduce conj #{} (for [i (range 10) j (range 10)] [i j]))

note that (for ..) here is only used to produce a seq containing all the values to compile into the single result set. Or, for example:

(reduce + 0 (range 100))
=> 4950
楠木可依 2024-12-14 12:57:29

clojure 有几个很棒的系统来管理可变状态。在这种情况下,您可能需要一个 atom 包含一组

其他选项:

  • a ref 如果需要进行多个更改(协调多个线程)
  • var 如果这将是单线程(var 在这里可以像原子一样工作)
  • 一个 agent 如果你想设置值 当然,for已经异步

返回一个序列,所以你可能只想

 (into #{} (for [ i (range 10)
                  j (range 10) ]
             [i j]))

clojure has a several great systems for managing mutable state. in this case you may want an atom containing a set

your other options are:

  • a ref if more than one change needs to made (coordinated many threads)
  • a var if this will be single threaded (a var may work just as well here as an atom)
  • an agent if you wanted to set the value of s asynchronously

of course for returns a sequence already so you may just want

 (into #{} (for [ i (range 10)
                  j (range 10) ]
             [i j]))
丑疤怪 2024-12-14 12:57:29

我认为在这种情况下你也可以使用一些瞬态数据结构。

(let [s (transient #{})]
 (for [ i (range 10)
        j (range 10) ]
  (assoc! s i j)))
(persistent! s)

只是代码示例,未经测试。

I think you can also use some transient data structure in this scenario.

(let [s (transient #{})]
 (for [ i (range 10)
        j (range 10) ]
  (assoc! s i j)))
(persistent! s)

Just a code sample, not tested.

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