2011-09-29 83 views
3

我想创建一个数字的倍数的列表。例如[2; 4; 6; 8; 10]将是0到10之间的2的整数倍。F#创建x的倍数列表?

我该如何动态创建x的倍数列表?是否有可能没有设置上限呢?

做到这一点的一种方法是创建一个介于0和一些疯狂的大数字之间的列表,然后使用mod函数对其进行过滤。试图测试这个,创建一个0到一个疯狂的大数目列表导致了内存不足的异常(30秒左右后等待)。

我觉得F#有一些超级简单而且很棒的方式来创建这样的列表,但我太了解它是什么了。帮帮我?

回答

3

这将产生数倍的无限序列:

let multiples n = Seq.unfold (fun i -> Some(i, i + n)) n 

multiples 3 |> Seq.take 3 //seq [3; 6; 9] 

这是更多的代码,但速度更快:

let multiples n = 
    let rec loop i = 
    seq { 
     yield i 
     yield! loop (i + n) 
    } 
    loop n 

这基本上等同于下面的C#:

static IEnumerable<int> Multiples(int n) { 
    int i = n; 
    while (true) { 
     yield return i; 
     i += n; 
    } 
} 
3

序列(IEnumerables)给予懒惰你想在这里:

let multiplesOfN n = 
    seq { 
     for i in 1 .. 1000000 do 
      yield i * n 
    } 

let first6multsof3 = 
    multiplesOfN 3 |> Seq.take 6 

printfn "%A" (first6multsof3 |> Seq.toList) 

或与您的过滤器MOD策略:

seq { 1 .. 1000000} |> Seq.filter (fun x -> x%3=0) |> Seq.take 6 |> Seq.toList 
+0

StackOverflow的。您提出问题的地方,以及您在后面寻找确切答案的地方。 – Matthew

1
List.init 10 ((*) 3) 
val it : int list = [0; 3; 6; 9; 12; 15; 18; 21; 24; 27] 

您可以用参数玩,Seq.skip得到任何你所需要的。

例如,对于[2; 4; 6; 8; 10]

List.init 6 ((*) 2) 
|> List.tail 

或者:

List.init 6 ((*) 2) 
|> Seq.skip 1 
|> List.ofSeq 
1
[ firstValue..Step..endValue] 

[2..2..10] => [2; 4; 6; 8; 10]

其他方式

Seq.initInfinite id |> Seq.map (((+) 1) >> ((*) 2)) 
+0

+1。或'seq {2..2..10}'用于延迟序列。耻辱F#没有开放式范围表达式(例如Haskell中的[[2.4 ..]') –

+0

range为int,Limit max System.Int32.MaxValue:2147483647。同样由展开 – BLUEPIXY