如何使用Haskell高阶filter函数筛选指定股票代码的交易日志?
用Haskell的filter函数筛选交易日志
先搞懂filter的基本用法
和你熟悉的map不同,map是对列表里的每个元素做转换,而filter是筛选出符合条件的元素。它的类型签名是:
filter :: (a -> Bool) -> [a] -> [a]
第一个参数是一个返回布尔值的谓词函数(用来判断元素是否符合条件),第二个参数是待筛选的列表,最终返回所有满足条件的元素组成的新列表。
针对需求实现函数
你的目标是根据指定股票代码,从交易日志里筛选出对应记录。每条交易记录是一个5元组,其中第4个元素(字符串类型)是股票代码。
写法1:用lambda表达式直接实现
直接在filter里写匿名函数,解构5元组并判断股票代码是否匹配:
get_trades :: String -> [(Char, Int, Int, String, Int)] -> [(Char, Int, Int, String, Int)] get_trades targetStock log = filter (\(_, _, _, stock, _) -> stock == targetStock) log
这里的\(_, _, _, stock, _)是lambda表达式,只取出元组里的第4个元素(股票代码),和传入的targetStock做比较。
写法2:抽离判断逻辑(更易读)
如果觉得lambda不够直观,可以把判断逻辑单独写成函数,再传给filter:
-- 定义判断函数:检查单条交易记录是否属于目标股票 isTargetStock :: String -> (Char, Int, Int, String, Int) -> Bool isTargetStock target (_, _, _, stock, _) = stock == target -- 实现筛选函数 get_trades :: String -> [(Char, Int, Int, String, Int)] -> [(Char, Int, Int, String, Int)] get_trades targetStock log = filter (isTargetStock targetStock) log
测试验证
调用get_trades "VTI" test_log,就能得到你想要的结果:
[('B',100,1104,"VTI",1),('B',50,1223,"VTI",5),('S',150,1240,"VTI",9)]
说说你之前的问题
你之前的代码有两个核心问题:
- 函数参数定义错误:
get_trades应该接收目标股票代码和交易日志列表两个参数,而不是直接解构单条交易记录; - 混淆了
map和filter的用途:这里不需要用map做元素转换,而是要用filter做条件筛选。
内容的提问来源于stack exchange,提问作者user13744763
相关产品推荐
相关产品推荐

