2010-09-16 15 views
10
, Hem fiyat ilk anahtarı nerede, azalan ve artan düzende ve iki kayıtlar varsa ben o zaman ben kimliği ve fiyata göre sıralamak istediğiniz kayıtların bir listesi var

Erlang kayıtlarını bir listede mi sıralıyorsunuz?

-record(myrec, 
    { 
     id = 0, 
     price = 0, 
     quantity = 0 
    }). 

:

ben erlang bir kayıt var aynı fiyata bunları id olarak sıralamak istiyorum.

Bunun için nasıl bir eğlence tanımlayabilirim?

Ben Erlang bir newb değilim :)

sayesinde nisbus

cevap

14

Bu, şimdiye kadar önerilenlerden daha kısa bir çözümdür. Öncelikle kayıt tanımlayın:

1> rd(myrec, {id=0, price=0, quantity=0}). 
myrec 

O halde 3 tanesi icat edelim:
2> A = #myrec{id=1, price=10, quantity=2}, B = #myrec{id=2, price=4, quantity=3}, C = #myrec{id=3, price=10, quantity=1}. 
#myrec{id = 3,price = 10,quantity = 1 

Şimdi bir karşılaştırma işlevi gerekir. Çözümün daha kısa olduğu yer burası. Erlang göründükleri sırayla tuple koşullarını karşılaştırabilirsiniz, bu yüzden fiyata göre sıralamak istiyorsanız, o zaman id tarafından, sadece formun {PriceA, IdA} < {PriceB, IdB} iki dizilerini karşılaştırmak zorunda:

3> F = fun(X, Y) -> {X#myrec.price, X#myrec.id} < {Y#myrec.price, Y#myrec.id} end. 
#Fun<erl_eval.12.113037538> 

Ve lists:sort/2 takın :

4> lists:sort(F, [C,B,A]). 
[#myrec{id = 2,price = 4,quantity = 3}, 
#myrec{id = 1,price = 10,quantity = 2}, 
#myrec{id = 3,price = 10,quantity = 1}] 

sipariş ver [B, A, C] bağlıdır ve liste sıralanır. Eğer kimliği yerine azalan göre sıralamak için istiyorsa aşağıdaki gibi bir küpe de kimlikleri tersine çevirerek onu kandırmak verebilecek

Not:

5> G = fun(X, Y) -> {X#myrec.price, Y#myrec.id} < {Y#myrec.price, X#myrec.id} end. 
#Fun<erl_eval.12.113037538> 
6> lists:sort(G, [C,B,A]).              
[#myrec{id = 2,price = 4,quantity = 3}, 
#myrec{id = 3,price = 10,quantity = 1}, 
#myrec{id = 1,price = 10,quantity = 2}] 

bize [B, C, A] verilmesi. Bu okuyucu için açık değil, bu yüzden daha iyi belgeleyebilir veya Dustin'in çözümünü kullanabilirsiniz. Burada sunulan çözümün avantajı, yuvalama gerektirmemesidir. Tuple'daki öğeleri karşılaştırmada ayarlayarak, kodu çok daha uzun süre kullanmadan, istediğiniz kadar çoğunu karşılaştırabilirsiniz.

+0

Bu sadece soğuk. Teşekkürler – nisbus

+0

Bu durumda o zaman neden sadece bir fonksiyon tanımlamak f, neden sadece listeleri: sort ([C, B, A])? – Vishal

0
% 3723064 

-module(t). 
-export([record_sort/0, price_cmp/2, qty_cmp/2]). 

-record (item, {id = 0, price = 0, quantity = 0}). 

price_cmp(A, B) -> 
    A#item.price < B#item.price. 

qty_cmp(A, B) -> 
    A#item.quantity < B#item.quantity. 

record_sort() -> 
    Items = [ 
     #item{id=1, price=10, quantity=5}, 
     #item{id=2, price=50, quantity=0}, 
     #item{id=3, price=30, quantity=3}, 
     #item{id=4, price=60, quantity=9} 
    ], 
    io:format("Unsorted Items: ~p~n", [Items]), 
    io:format("By Price: ~p~n", [lists:sort({t, price_cmp}, Items)]), 
    io:format("By Quantity: ~p~n", [lists:sort({t, qty_cmp}, Items)]). 

    % Alternatively use anonymous functions: 

    % io:format("By Price: ~p~n", [lists:sort(
    % fun(A, B) -> A#item.price < B#item.price end, Items)]), 
    % 
    % io:format("By Quantity: ~p~n", [lists:sort(
    % fun(A, B) -> A#item.quantity < B#item.quantity end, Items)]). 

Bu verecektir nisbus (varsayarak örnek dosya t.erl):

1> c(t).   
{ok,t} 
2> t:record_sort(). 
Unsorted Items: [{item,1,10,5},{item,2,50,0},{item,3,30,3},{item,4,60,9}] 
By Price: [{item,1,10,5},{item,3,30,3},{item,2,50,0},{item,4,60,9}] 
By Quantity: [{item,2,50,0},{item,3,30,3},{item,1,10,5},{item,4,60,9}] 
ok 
2

İlk olarak, anlamaya Kayıtlarınızı nasıl karşılaştırılır:

-spec compare(#myrec{}, #myrec{}) -> boolean(). 
compare(A, B) -> 
    case A#myrec.price == B#myrec.price of 
     true -> 
      A#myrec.id < B#myrec.id; 
     _ -> 
      B#myrec.price < A#myrec.price 
    end. 

Sonra, sadece istediğini elde etmek için karşılaştırma fonksiyonu normal lists:sort işlevini kullanın (bu ben yapmak ran yukarıda bir eunit testtir ben mantıklı bir şey yaptım emin):

compare_test() -> 
    R1 = #myrec{id=5, price=3, quantity=2}, 
    R2 = #myrec{id=6, price=5, quantity=1}, 
    R3 = #myrec{id=7, price=5, quantity=0}, 

    false = compare(R1, R2), 
    true = compare(R2, R1), 

    true = compare(R2, R3), 
    false = compare(R3, R2), 

    false = compare(R1, R3), 
    true = compare(R3, R1), 

    % Run a sort with the above comparator. 
    [R2, R3, R1] = lists:sort(fun compare/2, [R1, R2, R3]). 
+0

Teşekkürler, bu hile yapar. – nisbus