Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 排序和运行查询示例_Search_F#_Design Patterns_Sequence_Repeat - Fatal编程技术网

Search 排序和运行查询示例

Search 排序和运行查询示例,search,f#,design-patterns,sequence,repeat,Search,F#,Design Patterns,Sequence,Repeat,我想获得一些关于如何使用F#/函数式编程来搜索列表中重复值的指针和/或示例代码 考虑以下用例: 给定一个列表/数组/日期序列和每个日期的最高温度,我想提取出连续n天温度高于给定阈值的初始日期 此类查询的另一个示例是搜索股票价格历史记录表/列表,查找在指定时间间隔(例如,至少30天)内超过给定阈值的价格。 在本例中,我要查找首次超过阈值的初始日期 TIA我可能会从一个效率较低但功能优雅的解决方案开始,该解决方案使用序列加窗功能(将序列转换为指定大小的连续组序列): 源代码 //创建指定大小的组 |

我想获得一些关于如何使用F#/函数式编程来搜索列表中重复值的指针和/或示例代码

考虑以下用例: 给定一个列表/数组/日期序列和每个日期的最高温度,我想提取出连续n天温度高于给定阈值的初始日期

此类查询的另一个示例是搜索股票价格历史记录表/列表,查找在指定时间间隔(例如,至少30天)内超过给定阈值的价格。 在本例中,我要查找首次超过阈值的初始日期


TIA

我可能会从一个效率较低但功能优雅的解决方案开始,该解决方案使用
序列加窗功能(将序列转换为指定大小的连续组序列):

源代码
//创建指定大小的组
|>Seq.加窗所需长度
//将起始索引添加到序列中
|>Seq.mapi(乐趣i v->i,v)
//查找仅包含大于treshold的数字的所有组
|>顺序过滤器(乐趣(i,v)->v |>顺序过滤器(顺序图fst
这将返回所有此类组的索引,因此如果存在多个重叠组(即,与条件匹配的较大序列),则您将获得所有起始索引。您可能只需从结果中筛选连续数字,以仅获得组的第一个索引(使用
Seq.fold


为了获得更有效的版本,您需要编写一个递归函数,在数组或列表上进行迭代。您可能需要记住(在函数参数中)在树型结构上找到最后一个值的时间。(这与命令式循环基本相同,只是您使用递归函数并在参数中保留状态).

虽然我喜欢Tomas代码的简洁性,但我还是忍不住认为他所暗示的更高效的版本在这里是必须的,特别是如果实际的比较逻辑比简单的整数比较更昂贵的话。我提交以下摘要:

let findWindowBeginnings predicate minWindowSize data =
    if minWindowSize < 2 then
        invalidArg "minWindowSize" "minWindowSize must be greater than 1"

    ((None, []), data)
    ||> Seq.fold (fun (window, acc) x ->
        if predicate x then
            match window with
            | Some (start, size) -> let size' = size + 1
                                    let acc' = if size' = minWindowSize
                                               then start::acc
                                               else acc
                                    Some (start, size'), acc'
            | _                  -> Some (x, 1), acc
        else None, acc)
    |> snd
    |> List.rev
让findwindowbeginings谓词minWindowSize数据=
如果MinWindowsSize小于2,则
invalidArg“MinWindowsSize”MinWindowsSize必须大于1
((无,[]),数据)
||>顺序折叠(乐趣(窗口,附件)x->
如果谓词x那么
匹配窗口
|一些(开始,大小)->让大小“=大小+1
让acc'=如果大小'=最小窗口大小
然后启动::acc
其他acc
一些(开始,尺寸),acc'
|部分(x,1),根据
其他(无,acc)
|>snd
|>List.rev
日期+温度元组序列的用例如下所示:

let findHeatwaveBeginnings tempThreshold consecutiveDays data =
    (consecutiveDays, data)
    ||> findWindowBeginnings (snd >> (<) tempThreshold)
    // alternatively, if you're not a fan of point-free style code:
    //  findWindowBeginnings (fun (_, maxTemp) -> maxTemp > tempThreshold)
    |> List.map fst
让FindHeatWaveBeginings尝试阈值连续日期数据=
(连续日期、数据)

||>FindwindowBeginings(snd>>(+1用于实际实现它!您介意将它发布到吗?人们经常会问类似的问题,并且通过键入工具提示阅读折叠更容易:-)
let findHeatwaveBeginnings tempThreshold consecutiveDays data =
    (consecutiveDays, data)
    ||> findWindowBeginnings (snd >> (<) tempThreshold)
    // alternatively, if you're not a fan of point-free style code:
    //  findWindowBeginnings (fun (_, maxTemp) -> maxTemp > tempThreshold)
    |> List.map fst