【问题标题】:Does this "filtering" function exist? What would be a good name for such a function?这个“过滤”功能是否存在?这种功能的好名字是什么?
【发布时间】:2015-01-23 04:02:46
【问题描述】:

我正在解决一个涉及具有特定属性的所有 n 位数字的 Project Euler 问题。似乎获得它们的最简单方法可能是获取具有该属性的所有数字的列表(这将是无限长的),然后选择具有正确位数的数字。像这样:

numsWithCoolProperty = filter hasCoolProperty [1..]

nDigitNumsWithCoolProperty n = takeWhile (< 10^n) $ dropWhile (<= 10^(n-1)) numsWithOtherCoolProperty

但是现在如果我想对不同的属性做同样的事情,我会重复自己:

nDigitNumsWithOtherCoolProperty n = takeWhile (< 10^n) $ dropWhile (<= 10^(n-1)) numsWithOtherCoolProperty

所以我想要一个捕获 dropWhile/takeWhile 逻辑的函数。比如:

f :: (a -> Bool) -> [a] -> [a]
f pred = takeWhile pred . dropWhile (not . pred)

如果我有一个谓词 hasNDigits n m 如果 m 有 n 位返回 true,我可以这样做:

nDigitNumsWithCoolProperty n = f (hasNDigits n) numsWithCoolProperty
nDigitNumsWithOtherCoolProperty n = f (hasNDigits n) numsWithOtherCoolProperty

无论如何,我的问题是关于函数f,它与dropWhile 和takeWhile 具有相同的类型:它是否已经存在于某个地方?如果不是,它的好名字是什么?我能想到的只是dropUntilTakeWhile 之类的东西,但我敢肯定那里有更好的名字。

【问题讨论】:

  • 您不需要使take until + drop while 递归吗?否则它只会在谓词匹配和非谓词匹配之间的单个转换上起作用。 (我完全不懂语法,所以我不知道你对f 的定义是否已经这样做了)
  • 在这种特殊情况下,我知道numsWithCoolProperty 已排序(我想我应该这么说),这意味着我知道所有三位数字都将组合在一起。当它从两位数转换为三位数时,我想开始包括那些,当它从三位数转换为四位数时,我想停止。如果我不知道列表已排序(或者与谓词匹配的所有数字都在一次运行中分组),那么我将使用filter。但我不能在这里这样做,因为它是一个无限列表,我想得到一个有限的返回。
  • 没什么帮助,但你可以称它为takeRange,并将谓词称为isInRange
  • 另一种方法怎么样:nDigitNums n = [10^(n-1)..10^n-1],然后对其进行过滤。
  • 我会简单地调用该函数dropTakeWhile。

标签: haskell functional-programming naming-conventions


【解决方案1】:

你的功能:

f pred = takeWhile pred . dropWhile (not . pred)

与span 和break 函数密切相关,如您所见:

span  :: (a -> Bool) -> [a] -> ([a], [a]) 

break :: (a -> Bool) -> [a] -> ([a], [a])       

让我们看一些例子:

> span (< 3) [1,2,3,4,1,2,3,4]
([1,2],[3,4,1,2,3,4])

> break (< 3) [1,2,3,4,1,2,3,4]
([],[1,2,3,4,1,2,3,4])

和你的功能:

> f (< 3) [1,2,3,4,1,2,3,4]
[1,2]

现在,我们有一项法律将span 与takeWhile 和dropWhile 联系起来,

span p xs 相当于 (takeWhile p xs, dropWhile p xs)

因此我们可能会将您的函数视为 span 和 break 函数组的一部分。它还与词法分析有关,您可以在其中收集一些与谓词匹配的标记。

因此,您可以将此函数称为 gather 或 lex 或类似名称。

【讨论】:

    猜你喜欢
    • 2018-12-19
    • 2011-11-23
    • 2015-01-15
    • 2019-09-22
    • 2020-12-11
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 2014-04-20
    相关资源
    最近更新 更多