你如何调用函数模式来获得应用函数的第一个非空结果?
How do you call the functional pattern to get first non null result of applying function?
是否有一个函数的 'canonical' 名称:
- 接收一个集合和一个函数
- 遍历集合
- 对于每个元素,调用函数
- 如果函数return是一个非空值,停止迭代并且return这个值
- 否则继续
理想情况下,每个元素最多应调用 'function' 一次。
示例实现(感觉有点笨拙)
// xs : collection of type 'a
// f : function from type 'a to type 'b
// returns : an element of type 'b, or nothing
function what_is_in_a_name(xs, f) {
var res = null;
_.find(function (item) {
res = f(item);
return res !== null;
});
return res;
}
这听起来好像可以实现类似于 firstThat
之类的函数,其中首先将一个集合和一个 returns 布尔值函数作为参数,并且 returns满足谓词的第一个元素。在 Haskell、
firstThat :: (a -> Bool) -> [a] -> a
firstThat f (x:xs)
| f x == True = x --returns the item
| otherwise = first f xs
这不是您要找的 100%,但可以修改以完成工作(在您选择的语言中,当然有 null
值!)。
正如您已经发现的那样,它可以分解为通用模式“找到满足谓词的集合中的第一个元素”,几乎任何语言都有一个函数(例如,find_if
在 C++ 中或 find
在 Haskell 中)。然后它可以与另一个辅助函数结合使用传递函数的结果,就像这个 Haskell 片段:
firstApply :: (a -> Maybe b) -> [a] -> Maybe b
firstApply f = fmap f . find (isJust . f)
--or
firstApply f = join . find isJust . map f
--or
firstApply f = mconcat . map f
否则,您也可以手动完成任务,就像@zcleghern 所做的那样。命令式变体也适合此描述,区别仅在于实现。在大多数命令式语言中,您可能会使用循环遍历集合,在纯函数式语言中 - 使用递归。
您的实现是两种方式的混合:高阶 find
带有来自 FP 的闭包 (res),来自 IP 的可变引用和手动案例处理。
对 FP 了解很多,您也可以根据更一般或更抽象的方式来制定任务(例如,此函数可以被视为变形或折叠的特例),但我想它会是不必要的复杂化。
是否有一个函数的 'canonical' 名称:
- 接收一个集合和一个函数
- 遍历集合
- 对于每个元素,调用函数
- 如果函数return是一个非空值,停止迭代并且return这个值
- 否则继续
理想情况下,每个元素最多应调用 'function' 一次。
示例实现(感觉有点笨拙)
// xs : collection of type 'a
// f : function from type 'a to type 'b
// returns : an element of type 'b, or nothing
function what_is_in_a_name(xs, f) {
var res = null;
_.find(function (item) {
res = f(item);
return res !== null;
});
return res;
}
这听起来好像可以实现类似于 firstThat
之类的函数,其中首先将一个集合和一个 returns 布尔值函数作为参数,并且 returns满足谓词的第一个元素。在 Haskell、
firstThat :: (a -> Bool) -> [a] -> a
firstThat f (x:xs)
| f x == True = x --returns the item
| otherwise = first f xs
这不是您要找的 100%,但可以修改以完成工作(在您选择的语言中,当然有 null
值!)。
正如您已经发现的那样,它可以分解为通用模式“找到满足谓词的集合中的第一个元素”,几乎任何语言都有一个函数(例如,find_if
在 C++ 中或 find
在 Haskell 中)。然后它可以与另一个辅助函数结合使用传递函数的结果,就像这个 Haskell 片段:
firstApply :: (a -> Maybe b) -> [a] -> Maybe b
firstApply f = fmap f . find (isJust . f)
--or
firstApply f = join . find isJust . map f
--or
firstApply f = mconcat . map f
否则,您也可以手动完成任务,就像@zcleghern 所做的那样。命令式变体也适合此描述,区别仅在于实现。在大多数命令式语言中,您可能会使用循环遍历集合,在纯函数式语言中 - 使用递归。
您的实现是两种方式的混合:高阶 find
带有来自 FP 的闭包 (res),来自 IP 的可变引用和手动案例处理。
对 FP 了解很多,您也可以根据更一般或更抽象的方式来制定任务(例如,此函数可以被视为变形或折叠的特例),但我想它会是不必要的复杂化。