Erlang 列表的操作

2022-07-07 15:39 更新

Erlang 更多關(guān)于列表的內(nèi)容

| 操作符可以用于取列表中的首元素:

47> [M1|T1] = [paris, london, rome].
[paris,london,rome]
48> M1.
paris
49> T1.
[london,rome]

同時(shí),| 操作符也可以用于在列表首部添加元素:

50> L1 = [madrid | T1].
[madrid,london,rome]
51> L1.
[madrid,london,rome]

使用 | 操作符操作列表的例子如下 -- 翻轉(zhuǎn)列表中的元素:

-module(tut8).

-export([reverse/1]).

reverse(List) ->
    reverse(List, []).

reverse([Head | Rest], Reversed_List) ->
    reverse(Rest, [Head | Reversed_List]);
reverse([], Reversed_List) ->
    Reversed_List.
52> c(tut8).
{ok,tut8}
53> tut8:reverse([1,2,3]).
[3,2,1]

仔細(xì)捉摸一下,Reversed_List 是如何被創(chuàng)建的。初始時(shí),其為 []。隨后,待翻轉(zhuǎn)的列表的首元素被取出來(lái)再添加到 Reversed_List 列表中,如下所示:

reverse([1|2,3], []) =>
    reverse([2,3], [1|[]])

reverse([2|3], [1]) =>
    reverse([3], [2|[1])

reverse([3|[]], [2,1]) =>
    reverse([], [3|[2,1]])

reverse([], [3,2,1]) =>
    [3,2,1]

lists 模塊中包括許多操作列表的函數(shù),例如,列表翻轉(zhuǎn)。所以,在自己動(dòng)手寫操作列表的函數(shù)之前是可以先檢查是否在模塊中已經(jīng)有了(參考 STDLIB 中 lists(3) 手冊(cè))。

下面讓我們回到城市與溫度的話題上,但是這一次我們會(huì)使用更加結(jié)構(gòu)化的方法。首先,我們將整個(gè)列表中的溫度都使用攝氏度表示:

-module(tut7).
-export([format_temps/1]).

format_temps(List_of_cities) ->
    convert_list_to_c(List_of_cities).

convert_list_to_c([{Name, {f, F}} | Rest]) ->
    Converted_City = {Name, {c, (F -32)* 5 / 9}},
    [Converted_City | convert_list_to_c(Rest)];

convert_list_to_c([City | Rest]) ->
    [City | convert_list_to_c(Rest)];

convert_list_to_c([]) ->

測(cè)試一下上面的函數(shù):

54> c(tut7).
{ok, tut7}.
55> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
[{moscow,{c,-10}},
 {cape_town,{c,21.11111111111111}},
 {stockholm,{c,-4}},
 {paris,{c,-2.2222222222222223}},
 {london,{c,2.2222222222222223}}]

含義如下:

format_temps(List_of_cities) ->
    convert_list_to_c(List_of_cities).

format_temps/1 調(diào)用 convert_list_to_c/1 函數(shù)。covert_list_to_c/1 函數(shù)移除 List_of_cities 的首元素,并將其轉(zhuǎn)換為攝氏單位表示 (如果需要)。| 操作符用來(lái)將被轉(zhuǎn)換后的元素添加到轉(zhuǎn)換后的剩余列表中:

[Converted_City | convert_list_to_c(Rest)];

或者:

[City | convert_list_to_c(Rest)];

一直重復(fù)上述過(guò)程直到列表空為止。當(dāng)列表為空時(shí),則執(zhí)行:

convert_list_to_c([]) ->
    [].

當(dāng)列表被轉(zhuǎn)換后,用新增的打印輸出函數(shù)將其輸出:

-module(tut7).
-export([format_temps/1]).

format_temps(List_of_cities) ->
    Converted_List = convert_list_to_c(List_of_cities),
    print_temp(Converted_List).

convert_list_to_c([{Name, {f, F}} | Rest]) ->
    Converted_City = {Name, {c, (F -32)* 5 / 9}},
    [Converted_City | convert_list_to_c(Rest)];

convert_list_to_c([City | Rest]) ->
    [City | convert_list_to_c(Rest)];

convert_list_to_c([]) ->
    [].

print_temp([{Name, {c, Temp}} | Rest]) ->
    io:format("~-15w ~w c~n", [Name, Temp]),
    print_temp(Rest);
print_temp([]) ->
    ok.
56> c(tut7).
{ok,tut7}
57> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
moscow          -10 c
cape_town       21.11111111111111 c
stockholm       -4 c
paris           -2.2222222222222223 c
london          2.2222222222222223 c
ok

接下來(lái),添加一個(gè)函數(shù)來(lái)搜索擁有最高溫度與最低溫度值的城市。下面的方法并不是最高效的方式,因?yàn)樗闅v了四次列表。但是首先應(yīng)當(dāng)保證程序的清晰性和正確性,然后才是想辦法提高程序的效率:

-module(tut7).
-export([format_temps/1]).

format_temps(List_of_cities) ->
    Converted_List = convert_list_to_c(List_of_cities),
    print_temp(Converted_List),
    {Max_city, Min_city} = find_max_and_min(Converted_List),
    print_max_and_min(Max_city, Min_city).

convert_list_to_c([{Name, {f, Temp}} | Rest]) ->
    Converted_City = {Name, {c, (Temp -32)* 5 / 9}},
    [Converted_City | convert_list_to_c(Rest)];

convert_list_to_c([City | Rest]) ->
    [City | convert_list_to_c(Rest)];

convert_list_to_c([]) ->
    [].

print_temp([{Name, {c, Temp}} | Rest]) ->
    io:format("~-15w ~w c~n", [Name, Temp]),
    print_temp(Rest);
print_temp([]) ->
    ok.

find_max_and_min([City | Rest]) ->
    find_max_and_min(Rest, City, City).

find_max_and_min([{Name, {c, Temp}} | Rest], 
         {Max_Name, {c, Max_Temp}}, 
         {Min_Name, {c, Min_Temp}}) ->
    if 
        Temp > Max_Temp ->
            Max_City = {Name, {c, Temp}};           % Change
        true -> 
            Max_City = {Max_Name, {c, Max_Temp}} % Unchanged
    end,
    if
         Temp < Min_Temp ->
            Min_City = {Name, {c, Temp}};           % Change
        true -> 
            Min_City = {Min_Name, {c, Min_Temp}} % Unchanged
    end,
    find_max_and_min(Rest, Max_City, Min_City);

find_max_and_min([], Max_City, Min_City) ->
    {Max_City, Min_City}.

print_max_and_min({Max_name, {c, Max_temp}}, {Min_name, {c, Min_temp}}) ->
    io:format("Max temperature was ~w c in ~w~n", [Max_temp, Max_name]),
    io:format("Min temperature was ~w c in ~w~n", [Min_temp, Min_name]).
58> c(tut7).
{ok, tut7}
59> tut7:format_temps([{moscow, {c, -10}}, {cape_town, {f, 70}},
{stockholm, {c, -4}}, {paris, {f, 28}}, {london, {f, 36}}]).
moscow          -10 c
cape_town       21.11111111111111 c
stockholm       -4 c
paris           -2.2222222222222223 c
london          2.2222222222222223 c
Max temperature was 21.11111111111111 c in cape_town
Min temperature was -10 c in moscow
ok  
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)