【问题标题】:Filter elements from nested lists从嵌套列表中过滤元素
【发布时间】:2017-10-15 19:44:36
【问题描述】:

我很难理解函数式编程背后的逻辑。所以,这应该很容易,但不适合我。 我想做的是: 一个带有参数列表的函数,一个列表是这样的:[[1,2,3], [5,7,8,12,34], [2,4,6,8]] 首先我应该删除小于 6 的值,然后删除所有少于 2 个元素的列表。我的代码是这样的:

f11 :: [[Int]] -> [[Int]]
f11 xs = ( filter (\s -> if a <= 6 a then True else False )) (map (filter (\x -> length x <= 2)) xs)

【问题讨论】:

  • 小风格注释:可以避免反模式if condition then True else False,可以简化为condition。例如,可以写filter (\x -&gt; x&gt;=6) [1..10]

标签: list haskell filter


【解决方案1】:

您还可以使用do 表示法,这要归功于列表的Monad 实例。

f11 xss = do
    xs <- xss
    let ys = [x | x <- xs, x >= 6]
    guard (length ys <= 2)
    return ys
lists

do 符号基本上表示foreach 循环。我们从xss 中提取每个元素xs,然后通过列表推导过滤掉小于6 的元素,将结果命名为ys。然后guard 过滤掉大于2 的ys

【讨论】:

    【解决方案2】:

    反之,请检查:

    f11 :: [[Int]] -> [[Int]]
    f11  =  (filter \x-> length x < 2) . (map (filter \x -> x > 6))
    

    【讨论】:

    • 我认为使用无点谓词看起来也更好,但我想有些人可能不同意:f11 = filter ((&lt; 2) . length) . map (filter (&gt;= 6))
    • @amalloy 喜欢这个。更好
    • 谢谢。我只需要检查那些“点”的作用 =)
    • @Pelin,点表示功能组合,就像将两个功能行为合二为一。
    • 太棒了!感谢@Daniel Sanchez 的解释
    【解决方案3】:

    这是一个口味问题,但为了便于阅读,您可能希望使用中间体:

    f11 :: [[Int]] -> [[Int]]
    f11 xs = 
        let 
            less6Cleared = map (filter (\x -> x >= 6)) xs
        in  
            filter (\x -> length(x) >= 2) less6Cleared                       
    

    这表示less6Cleared 是所有元素已被清除的小于 6 的列表的列表。您现在对less6Cleared 应用过滤器。

    【讨论】:

      【解决方案4】:

      如果您想疯狂地使用无点样式和部分函数应用程序...

      f11 :: [[Int]] -> [[Int]]
      f11 = (filter $ (>= 2) . length) . (map $ filter (>= 6))
      

      ...但它可能不太清楚,尤其是对于那些不习惯它的人。

      另外我把你对“小于”的要求严格了,所以不删除 6 的值,不删除 2 的长度列表。

      【讨论】:

        猜你喜欢
        • 2023-02-18
        • 2022-07-13
        • 2022-01-06
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        • 2023-03-22
        • 1970-01-01
        相关资源
        最近更新 更多