- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我想要一个接收 Tuple
我想要做的是一个返回这种值的函数:
f( [1,10; 2,20; 3,40; 4,70] ) = [2,10; 3,20; 4,30]
所以如你所见,第一个数字基本不变(除了第一个项目没有被选中),但最后一个数字是当前数字与前一个数字的减法(20 - 10 = 10, 40 - 20 = 20, ...).
我试图在 F# 中提出一个不涉及可变性 的算法(对前一个值使用累加器意味着我需要一个可变变量),但我做不到弄清楚。这可能吗?
最佳答案
使用内置函数。在这种情况下,您可以使用 Seq.pairwise
.该函数采用一系列输入并生成一系列包含先前值和当前值的对。一旦你有了对,你就可以使用 Seq.map
将对转换为结果 - 在您的情况下,获取当前值的 ID 并从当前值中减去先前的值:
input
|> Seq.pairwise
|> Seq.map (fun ((pid, pval), (nid, nval)) -> nid, nval-pval)
请注意,结果是一个序列 (IEnumerable<T>
) 而不是一个列表 - 仅仅是因为 Seq
模块包含更多(有用的)功能。您可以使用 List.ofSeq
将其转换回列表.
使用显式递归。如果您的任务不符合某些内置函数所涵盖的常见模式之一,那么答案就是使用递归(通常, 替换功能样式中的突变)。
为了完整起见,递归版本看起来像这样(这并不完美,因为它不是尾递归,所以它可能会导致堆栈溢出,但它演示了这个想法):
let rec f list =
match list with
| (pid, pval)::(((nid, nval)::_) as tail) ->
(nid, nval-pval)::(f tail)
| _ -> []
这需要一个列表并查看列表的前两个元素 (pid, pval)
和 (nid, nval)
.然后它根据(nid, nval-pval)
中的两个元素计算出新值。然后递归处理列表的其余部分(tail
),跳过第一个元素。如果列表只有一个或更少的元素(第二种情况),则不返回任何内容。
可以使用“累加器”技巧编写尾递归版本。而不是写 newValue::(recursiveCall ...)
我们将新产生的值累积在一个列表中作为参数保存,然后反转它:
let rec f list acc =
match list with
| (pid, pval)::(((nid, nval)::_) as tail) ->
f tail ((nid, nval-pval)::acc)
| _ -> List.rev acc
现在您只需要使用 f input []
调用该函数即可初始化累加器。
关于f# - 处理没有可变性的元组流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22543930/
我通过它们的5 元组(src IP、dst 端口、sport、dport、传输协议(protocol)编号)识别互联网流量,我想将这个 5-元组为更紧凑的字母数字 ID,供我的脚本内部使用。 我在 P
我是一名优秀的程序员,十分优秀!