我不認爲德里克·布朗的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
).
在你的情況下,單獨的變量將持有迄今爲止最高分的學生。
在shell:
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()
。你可以想象,如果你有一個包含數百萬個元素的列表,那麼你應該儘可能少地遍歷列表。
名單:最大/ 1會給我最大的痕跡,但我想有最高分 –
'名單的人的ID:max'會給你整個元組。我已經在整個列表上嘗試了'lists:max'(沒有過濾),並且它返回:'{30,「Geo」,id3}' –
是的你是對的,列表:max/1接受元組的第一個元素,使用它來找到最大值。我嘗試將元組的順序改爲[{subject,marks,id}],並以數學作爲主題獲得元組作爲最大值。 –