如何在大小未知时使用 while..do 循环初始化 F# 列表
Posted
技术标签:
【中文标题】如何在大小未知时使用 while..do 循环初始化 F# 列表【英文标题】:How to initialize F# list when size is unknown, using while..do loop 【发布时间】:2010-05-24 02:32:12 【问题描述】:我有一个函数会解析 DataReader 的结果,但我不知道返回了多少项,所以我想使用 while..do
循环遍历读取器,结果应该是某种类型的列表。
(fun(reader) ->
[
while reader.Read() do
new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
])
这是我尝试过的,但我得到的警告是:
This expression should have type 'unit', but has type 'CityType'. Use 'ignore' to discard the result of the expression, or 'let'
to bind the result to a name.
那么迭代 DataReader 并创建列表的最佳方法是什么?
【问题讨论】:
我正试图找出完全相同的事情。很高兴你问。 +1 【参考方案1】:您可以使用列表推导:
[
while reader.Read() do
let d = new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1), StateName=(reader.GetString 2))
yield d
]
这里还有一个例子:
/// The squares of the first 10 integers
let squaresOfOneToTen = [ for x in 0..10 -> x*x ]
或
let squaresOfOneToTen = [ for x in 0..10 do yield x*x ]
你也可以对序列和数组这样做:
seq
for i=1 to 9 do
for j=1 to 9 do
yield (i,j,i*j)
[| for i=1 to 100 do yield i*i |]
你也可以在一个序列中产生一个子序列(yield!
),这里是一个使用Project Euler 31的例子。
【讨论】:
感谢您的帮助。我忘记了 yield 关键字。【参考方案2】:只是为了提供一些额外的信息来解释这里发生了什么 - 在 F# 中有两种创建列表的方法,在这两种情况下,您都在方括号 [ ... ]
中编写 something (一开始可能有点混乱!)
列表文字用于当您有几个表达式(已知数量的显式编写的表达式)并且想要创建一个包含评估这些表达式的结果的列表时。例如:
[ 1; 2; 3; ] // list of constant expressions
[ 1+1; 2+2; 3+3 ] // creates list [ 2; 4; 6 ]
列表推导在您有一些代码执行某些操作并生成元素列表(通过在计算期间生成元素)时使用。这就是殷竹在他的回答中使用的。一些例子是:
[ yield 1; ] // generates singleton list [ 1 ]
[ yield 1; yield 2; ] // generates list with two elements
[ for x in 1 .. 10 do // iterates loop 10 times
yield x * x ] // ... generates element during every iteration
高级功能
您也可以使用yield!
一次生成多个元素:
[ yield! [ 1; 2 ] // generates a list containing [ 1; 2; 3; 4 ]
yield! [ 3; 4 ] ]
这可用于编写递归函数,因此您可以使用递归而不是循环来重写您的代码(如果您需要保持某些状态,这将很有用,但从您的代码目前看来,while
非常好! )
let rec loop reader =
[ if reader.Read() then
yield new CityType(Id=(reader.GetInt32 0), Name=(reader.GetString 1),
StateName=(reader.GetString 2))
yield! loop reader ]
这是一种经常出现在列表推导中的模式,因此了解它很有用:-)。
【讨论】:
非常感谢您提供更多信息。我期望的最后一部分很快就会非常有用。 来自真正的 F# 专家!最近看了很多你的文章。谢谢:)以上是关于如何在大小未知时使用 while..do 循环初始化 F# 列表的主要内容,如果未能解决你的问题,请参考以下文章