4 f# for-loop functional-programming
我有一个字符串和数字列表,如下所示
let stringsAndNums = [("aa-",20); ("b1",20); ("aa",10); ("b12",10); ("+aa-",30)]
Run Code Online (Sandbox Code Playgroud)
我需要将列表分成一组包含在另一个中的字符串.
对于上述每个组,我必须找到最小值和最大值.
这是我试图做的:它正在工作,但我不认为这是惯用的F#,我想我应该避免for循环.
for tup in stringsAndNums do
let subject, value = tup
let related =
stringsAndNums |> List.filter(
fun o ->
let osubject, ovalue = o;
osubject.Contains(subject) || subject.Contains(osubject);
)
let relvalues = related |> List.map(fun o ->
let osubject, ovalue = o;
ovalue
)
let min = (relvalues |> List.min)
let max = (relvalues |> List.max)
printfn "%A" (subject, value, min, max, (max - min))
Run Code Online (Sandbox Code Playgroud)
另外,如何定义返回元组结果列表而不是打印它们的函数?
结果我看起来很好
("aa-", 20, 10, 30, 20)
("b1", 20, 10, 20, 10)
("aa", 10, 10, 30, 20)
("b12", 10, 10, 20, 10)
("+aa-", 30, 10, 30, 20)
Run Code Online (Sandbox Code Playgroud)
事实上,在这种情况下,两组是由
+aa-
值为30,aa
值为10,aa-
值为20,因此max为30,min为10b1
值20,b12
值10我现在要做的事情:现在不再有for循环了,但这段代码真的有用吗?
let results =
stringsAndNums |> List.map(fun tup ->
//for tup in stringsAndNums do
let subject, value = tup
let related =
stringsAndNums |> List.filter(
fun o ->
let osubject, ovalue = o;
osubject.Contains(subject) || subject.Contains(osubject);
)
//for reltup in related do
let relvalues = related |> List.map(fun o ->
let osubject, ovalue = o;
ovalue
)
let min = (relvalues |> List.min)
let max = (relvalues |> List.max)
printfn "%A" (subject, value, min, max, (max - min))
)
for result in results do
printf "%A" result
Run Code Online (Sandbox Code Playgroud)
这就是我写它的方式.
let subjectValues = [("aa-",20); ("b1",20); ("aa",10); ("b12",10); ("+aa-",30)]
let getRelated (subject, value) =
let relValues =
subjectValues
|> List.choose (fun (s, v) ->
if s.Contains(subject) || subject.Contains(s)
then Some v
else None)
let min = relValues |> List.min
let max = relValues |> List.max
(subject, value, min, max, (max - min))
let results = subjectValues |> List.map getRelated
printfn "%A" results
Run Code Online (Sandbox Code Playgroud)
它不能用于List.map
函数返回unit
(类似的东西void
).它产生了印刷副作用而不是价值.
元组模式匹配可以直接在函数参数中完成,而不是单独完成let
.
我通常会尝试编写作用于单个项目的函数,然后根据需要将其与List.map一起使用,因为我发现它更干净,更灵活.
我用一步替换List.map ... List.filter
了List.choose
两者.这具有删除中间难以命名的let
值的效果.
我希望,我重新命名了一些值,以赋予它们更多的意义.