-define(true, true). -define(false, false). %% 联盟的积分 -record(league_score, { score = 0, % 当前累计的积分 unixtime = 0, % 最后一次获取积分时的时间戳(积分排名时,如果累计积分相同,则此字段较小者获胜) rank = 0 % 积分排名(用于显示) }). foo() -> ScoreInfoList = [{105,{league_score,12,1448203750173,0}}, {108,{league_score,20,1448203897417,0}}], SortF = fun({LeagueId_A, LeagueScore_A}, {LeagueId_B, LeagueScore_B}) -> case LeagueScore_A#league_score.score > LeagueScore_B#league_score.score of ?true -> ?true; ?false -> ?false end end, lists:sort(SortF, ScoreInfoList). bar() -> ScoreInfoList = [{105,{league_score,12,1448203750173,0}}, {108,{league_score,20,1448203897417,0}}], SortF = fun({LeagueId_A, LeagueScore_A}, {LeagueId_B, LeagueScore_B}) -> case LeagueScore_A#league_score.score > LeagueScore_B#league_score.score of ?true -> ?true; ?false -> % ***** case LeagueScore_A#league_score.unixtime < LeagueScore_B#league_score.unixtime of ?true -> ?true; ?false -> LeagueId_A > LeagueId_B end end end, lists:sort(SortF, ScoreInfoList).
如上, foo函数和bar函数几乎是一样的,除了bar函数中标注*****的部分不一样之外,其他都一样。
本以为两个函数返回的结果应该是一样的, 但实际上完全相反:
50> b:foo().
[{108,{league_score,20,1448203897417,0}},
{105,{league_score,12,1448203750173,0}}]
51> b:bar().
[{105,{league_score,12,1448203750173,0}},
{108,{league_score,20,1448203897417,0}}]
52>
这个有可能是lists:sort实现的bug。
不过, bar函数中的SortF的判断逻辑本身是不正确的,判断时没有细化分为大于,小于, 以及等于的三种情况。 正确的判断应该是:
if LeagueScore_A#league_score.score > LeagueScore_B#league_score.score -> ?true; LeagueScore_A#league_score.score < LeagueScore_B#league_score.score -> ?false; ?true -> if LeagueScore_A#league_score.unixtime < LeagueScore_B#league_score.unixtime -> ?true; LeagueScore_A#league_score.unixtime > LeagueScore_B#league_score.unixtime -> ?false; ?true -> LeagueId_A > LeagueId_B end end
以上,脑袋迷糊的时候容易犯错,留意!
原文:http://www.cnblogs.com/kamfon/p/4987242.html