我认为 Derek Brown 的 lists:foldl() 解决方案无法正常工作。 lists:foldl() 允许您在维护和操作单独变量的同时单步执行列表。在处理完最后一个元素后,lists:foldl() 返回单独的变量。在这种情况下,您可以使用单独的变量来更新得分最高的学生。
您为lists:foldl() 提供了一个有趣的参数,它的参数是列表中的当前元素和您要操作的单独变量。 fun 的返回值是单独变量的新值。
max_mark(Students, Subject) ->
lists:foldl(
fun({M,S,_Id}=Student, {Highest,_,_}) when S=:=Subject, M>Highest -> Student;
(_Student, BestStudent) -> BestStudent
end,
{0, Subject, none}, %Starting value for the separate variable
Students %The list you want to step through
).
在您的情况下,单独的变量将保存迄今为止得分最高的学生。
在外壳中:
50> c(my).
{ok,my}
51> Students = [{10,"English",id1},{20,"Maths",id2},{30,"Geo",id3},{30,"Maths",id1},{30,"English",id4},{20,"English",id3}].
[{10,"English",id1},
{20,"Maths",id2},
{30,"Geo",id3},
{30,"Maths",id1},
{30,"English",id4},
{20,"English",id3}]
52> my:max_mark(Students, "English").
{30,"English",id4}
53> my:max_mark(Students, "Maths").
{30,"Maths",id1}
54> my:max_mark(Students, "Geo").
{30,"Geo",id3}
取得联系需要更多的工作。
使用lists:foldl() 的优点是您只需遍历列表一次即可获取所需信息,而不是使用filter() 遍历列表一次,然后使用max() 遍历列表第二次。您可以想象,如果您有一个包含数百万个元素的列表,那么您应该尽可能少地遍历该列表。