2010-09-16 18 views
10

मेरे पास एरलांग में एक रिकॉर्ड है:एक सूची में Erlang रिकॉर्ड छंटनी?

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

मेरे पास रिकॉर्ड की एक सूची है जो मैं आईडी और मूल्य से क्रमबद्ध और आरोही क्रम में क्रमबद्ध करना चाहता हूं, जहां कीमत पहली कुंजी है और यदि दो रिकॉर्ड हैं वही कीमत मैं आईडी द्वारा उनको सॉर्ट करना चाहता हूं।

मैं इसके लिए एक मजेदार कैसे परिभाषित कर सकता हूं?

मैं एरलांग में एक नया हूँ :)

धन्यवाद, nisbus

उत्तर

14

अब तक सुझाव दिया गया है कि यह एक छोटा सा समाधान है। सबसे पहले अपने रिकॉर्ड को परिभाषित:

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

तब के आविष्कार उनमें से 3 करते हैं:

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 

अब हम एक तुलना समारोह की जरूरत है। यह वह जगह है जहां समाधान छोटा है। Erlang क्रम में वे दिखाई देते में एक टपल के मामले की तुलना कर सकते हैं, इसलिए यदि हम मूल्य द्वारा क्रमबद्ध करना चाहते हैं, तो आईडी से, हम बस प्रपत्र {PriceA, IdA} < {PriceB, IdB} के दो tuples तुलना करने के लिए है:

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

और lists:sort/2 इसे प्लग :

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}] 

आदेश अब [B, A, C] है और अपनी सूची सॉर्ट हो जाता है।

नोट अगर आप उतरते आईडी बजाय द्वारा सॉर्ट करने के लिए चाहता था, आप इस प्रकार tuples में आईडी पीछे से यह धोखा हो सकता है कि:

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}] 

हमें [B, C, A] देते। यह पाठक के लिए स्पष्ट नहीं है, इसलिए आप इसे बेहतर तरीके से दस्तावेज करेंगे या इस मामले में डस्टिन के समाधान का उपयोग करेंगे। यहां प्रस्तुत समाधान का लाभ यह है कि कोई घोंसले की आवश्यकता नहीं है। तुलना में या तो टुपल में तत्वों को सेट करके, आप जितना अधिक चाहते हैं उतना अधिक कोड बनाये बिना जितना चाहें उतना अधिक तुलना कर सकते हैं।

+0

बस सादा ठंडा है। धन्यवाद – nisbus

+0

यह मामला है तो क्यों एक फ़ंक्शन f परिभाषित करें, क्यों न केवल सूचियां: क्रमबद्ध करें ([सी, बी, ए])? – 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)]). 

यह निकलेगा (यह मानते हुए उदाहरण फ़ाइल 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

सबसे पहले, आप यह पता लगाने अपने रिकॉर्ड की तुलना कैसे करें:

-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. 

उसके बाद, आप बस सामान्य lists:sort समारोह अपनी तुलना समारोह के साथ आप क्या चाहते हैं पाने के लिए उपयोग करते हैं (यह मैं बनाने के लिए भाग गया ऊपर के eunit परीक्षण है यकीन है कि मैं कुछ है कि समझ में बनाया किया):

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

धन्यवाद, यह चाल है। – nisbus

संबंधित मुद्दे