根据运营商添加数字列表(Adding a list of numbers based on an operator)

编程入门 行业动态 更新时间:2024-10-26 01:28:12
根据运营商添加数字列表(Adding a list of numbers based on an operator)

我是F#的新手,我正在努力适应整个函数式编程思维。 基本上我试图弄清楚如何迭代数字列表并将其加起来,而总和小于一定数量(例如200)。

目前我有以下几点:

let nums = [20 .. 50] let mutable total = 0 let addUp (num, (total : byref<int>)) = if (num + total < 200) then total <- total + num for num in nums do addUp (num, &total)

这确实完成了工作,但我觉得必须有一个更合适的方法来做到这一点,同时仍然保持在函数式编程的风格,而不必依赖于mutable。 我仍然觉得我正在接近强制性思维方式。

我以为我可以以某种方式使用List.fold来做到这一点,但经过一些实验,我无法弄清楚如何结合整体使用它而<200的事情。 任何帮助都会非常感激,如果这是一个常见问题和回答的问题,我会提前道歉(我通过自己的搜索找不到任何东西)。

I am really new to F# and am struggling to adapt to the whole functional programming mindset. Basically I am trying to figure out how to iterate through a list of numbers and add them up while the sum is less than a certain number (200 for instance).

At the moment I have something along the lines of the following:

let nums = [20 .. 50] let mutable total = 0 let addUp (num, (total : byref<int>)) = if (num + total < 200) then total <- total + num for num in nums do addUp (num, &total)

This does get the job done, but I feel like there must be a more appropriate way to do this while still remaining within the style of functional programming, and without out having to rely on a mutable. I still feel like I'm approaching things from an imperative mindset.

I was thinking I could somehow use List.fold to do this but after some experimentation I was unable to figure out how to utilize it in conjunction with the whole while < 200 thing. Any help would be hugely appreciated and I apologize in advance if this is a commonly asked and answered question (I couldn't find anything through my own search).

最满意答案

出于教育目的,上面的答案很好,因为它可以让你看到在fold或reduce内部究竟发生了什么。

对于实际项目,最好使用现有的库函数。 您甚至可以将求和和绑定检查分开。 考虑一下:

let addUp threshold xs = xs |> Seq.scan (+) 0 // line 1 |> Seq.takeWhile (fun x -> x < threshold) // line 2 |> Seq.last // line 3 // Usage: let nums = Seq.initInfinite ( (+) 20) // line 4 nums |> addUp 200 |> printfn "%d" // prints "188"

一点解释:

第1行是Seq.scan (fun state x -> state + x) 0的收缩,因此它实际上返回一系列中间和( Seq.scan (fun state x -> state + x) 0 20, 41, 63, ... ); 在第2行中,我们只选择匹配或过滤谓词的元素; 在第3行中,我们简单地取最后一个元素(与上面的过滤相匹配); 在第4行,再次,它是Seq.initInfinite (fun x -> 20+x)的收缩Seq.initInfinite (fun x -> 20+x) 。 我冒昧地让你的数据成为一个无限的序列( 20, 21, 22, ... ),但它仍然有效。

注意 ,代码看起来像三个调用,但序列只被评估一次。

注意 ,在第2行中,不要像上面那样尝试收缩。 原因是(<) threshold评估为fun x -> threshold < x这是错误的。 如果你。 但是,使用(>) threshold ,它反直觉和混乱。

注意 ,函数中没有错误检查。 使用空源序列调用它将在Seq.last崩溃。

For educational purposes, the answer above is fine as it lets you see what exactly happens within the fold or reduce.

For a real project, it is better to use existing library functions. You can even separate summation and bound checking. Consider this:

let addUp threshold xs = xs |> Seq.scan (+) 0 // line 1 |> Seq.takeWhile (fun x -> x < threshold) // line 2 |> Seq.last // line 3 // Usage: let nums = Seq.initInfinite ( (+) 20) // line 4 nums |> addUp 200 |> printfn "%d" // prints "188"

A bit of explanation:

line 1 is a contraction of Seq.scan (fun state x -> state + x) 0 so it actually returns a sequence of intermediate sums (20, 41, 63, ...); in line 2, we take only the elements that match or filtering predicate; in line 3, we simply take the last element (that matched the filtering above); in line 4, again, it's a contraction of Seq.initInfinite (fun x -> 20+x). I took my liberty to make your data an infinite sequence (20, 21, 22, ...), but it still works.

Note, the code looks like three calls, but the sequence is evaluated only once.

Note, in line 2, don't try contraction like above. The reason is that (<) threshold evaluates to fun x -> threshold < x which is wrong. If you. however, use (>) threshold, it reads counter-intuitive and confusing.

Note, there's no error checking in the function. Calling it with an empty source sequence will crash at Seq.last.

更多推荐

本文发布于:2023-07-29 14:10:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1316769.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:运营商   数字   列表   Adding   operator

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!