替换元素周围范围内的列表中的值

时间:2015-05-27 12:27:45

标签: f#

请考虑以下事项:

它是一个采用列表,阈值和宽度的例程,并生成一个数组,其中包含列表中元素低于阈值的元素。 如果索引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的宽度索引操作?

1 个答案:

答案 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 )