请考虑以下事项:
它是一个采用列表,阈值和宽度的例程,并生成一个数组,其中包含列表中元素低于阈值的元素。
如果索引i
的列表中的值高于阈值,则w
周围宽度为i
的结果数组中的元素将被-1
消隐。
let a = [1;4;1;4;3;3;2]
let w = 1
let thresh = 3
let res = Array.copy (a |> List.toArray)
let mutable i = 0
let N = a.Length
while i < N do
if a.[i] > thresh then
let lower = if i-w < 0 then 0 else i-w
let upper = if i+w > N-1 then N-1 else i+w
for j in lower..upper do
res.[j] <- -1
i <- i + 1
此示例的输出应为
[|-1; -1; -1; -1; -1; 3; 2|]
虽然这有效,但我想知道是否可以使用F#以更实用的方式完成这种带有list / seqs / arrays的宽度索引操作?
答案 0 :(得分:4)
将其转换为更具功能性的方法的关键是根据数据转换进行思考。您希望根据特定范围内的值返回值,因此首先要做的是将数据转换为一组范围,然后执行此操作。
此解决方案看起来有点滑稽,因为Windowed
无法在部分窗口上运行,因此您需要预先附加阈值(或更低)。
let replaceValues lst threshold width =
seq {
for n in 1 .. width -> threshold
yield! lst
for n in 1 .. width -> threshold
}
|> Seq.windowed (width * 2 + 1)
|> Seq.map (fun x->
if x |> Seq.exists (fun x->x > threshold) then -1
else x |> Seq.skip width |> Seq.head )