【问题标题】:How to generate integer ranges in Erlang?如何在 Erlang 中生成整数范围?
【发布时间】:2011-06-19 18:05:22
【问题描述】:

从我编程的其他语言中,我习惯了有范围。在 Python 中,如果我想要从 1 到 100 的所有数字,我会写 range(1, 101)。同样,在 Haskell 中我会写 [1..100],在 Scala 中我会写 1 to 100

我在 Erlang 中找不到类似的东西,无论是在语法还是库中。我知道我自己实现这将相当简单,但我想首先确保它在其他地方不存在(特别是因为标准库或语言实现的加载效率会更高)。

有没有办法在 Erlang 语言或标准库中做范围?还是我缺少一些成语?我只是想知道我是否应该自己实现它。

我也对我不想在 Erlang 中使用范围的可能性持开放态度(我不想在 Erlang 中编写 Python 或 Haskell)。另外,如果我确实需要自己实现这一点,如果您对提高性能有任何好的建议,我很想听听他们:)

【问题讨论】:

  • 很难说你是否做错了事。你只是说你是如何尝试做某事的,而不是你想要做什么。
  • @Dustin 我想我的意思是我想知道我是否像在 Erlang 中那样思考。
  • 正如 btilly 指出的那样,lists:seq/2 是要走的路!我通常可以推荐查看列表模块,它真的非常强大。哦,看看erldocs.com
  • 如果您不告诉我们您在想什么,就无法判断您是否在考虑正确的事情。有功能可以做你所要求的确切事情,但这并不意味着它是做任何你想做的事情的正确方法。有可能。但是,没有足够的信息来做出判断。

标签: erlang range


【解决方案1】:

http://www.erlang.org/doc/man/lists.html 看来,lists:seq(1, 100) 可以满足您的需求。您也可以使用lists:seq(1, 100, 2) 之类的操作来获取该范围内的所有奇数。

【讨论】:

    【解决方案2】:

    您可以使用list:seq(From, TO) 即@bitilly,也可以使用列表推导来添加更多功能,例如:

    1> [X || X <- lists:seq(1,100), X rem 2 == 0].
    [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,
     44,46,48,50,52,54,56,58|...]
    

    【讨论】:

      【解决方案3】:

      Ruby 中的 range 和 Erlang 中的 list:seq 是有区别的。 Ruby 的 range 不会创建列表并依赖 next 方法,因此 (1..HugeInteger).each { ... } 不会占用内存。 Erlang lists:seq 将创建列表(或者我相信它会)。因此,当范围用于副作用时,它确实会产生影响。

      附:不只是为了副作用:

      (1..HugeInteger).inject(0) { |s, v| s + v % 1000000 == 0 ? 1 : 0 }
      

      将与每个都以相同的方式工作,而不是创建列表。 Erlang 的方法是创建一个递归函数。其实反正就是一个隐藏的循环。

      【讨论】:

      • 是的,Erlang 没有惰性求值的方法。
      • @Rafe 当然可以!只是使用乐趣。
      • @Daniel 诅咒我对语言的早期判断。我应该进一步阅读教程。
      • @DanielYankowsky,你将如何在 Erlang 中实现带有乐趣的惰性流?假设我们需要惰性地遍历 [1..100] 范围内的所有奇数。
      • @Sharas 快速的回答是使用生成器函数,给定流中的值,可以生成下一个值。因此,“惰性列表”将是 {initial value, generator function} 的元组。如果这还不够强大,您可以让生成器函数生成流的整个尾部......(作为流本身)将是{初始值,生成器函数}的元组。当然,没有一个内置的列表函数可以在这样的流上工作,所以你需要实现你需要的那些。有关更多信息,请向 SO 发布一个新问题...有人会回答。
      【解决方案4】:

      Erlang 中的惰性流示例。虽然它不是 Erlang 特有的,但我想它可以用任何带有 lambda 的语言来完成。每次流高级时都会创建新的 lambda,因此可能会给垃圾收集器带来一些压力。

      range(From, To, _) when From > To ->
          done;
      range(From, To, Step) ->
          {From, fun() -> range(From + Step, To, Step) end}.
      
      list(done) ->
          [];
      list({Value, Iterator}) ->
          [Value | list(Iterator())].
      
      % ----- usage example ------
      
      list_odd_numbers(From, To) ->
          list(range(From bor 1, To, 2)).
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-11
        • 2010-09-26
        • 1970-01-01
        相关资源
        最近更新 更多