How to order a list according to an arbitrary order











up vote
0
down vote

favorite












I searched a relevant question but couldn't find one. So my question is how do I sort an array based on an arbitrary order. For example, let's say the ordering is:



order_of_elements = ['cc', 'zz', '4b', '13']


and my list to be sorted:



list_to_be_sorted = ['4b', '4b', 'zz', 'cc', '13', 'cc', 'zz']


so the result needs to be:



ordered_list = ['cc', 'cc', 'zz', 'zz', '4b', '4b', '13']


please note that the reference list(order_of_elements) describes ordering and I don't ask about sorting according to the alphabetically sorted indices of the reference list.



You can assume that order_of_elements array includes all the possible elements.



Any pseudocode is welcome.










share|improve this question
























  • Any complexity requirements?
    – Nelfeal
    Nov 8 at 9:58










  • Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
    – MGoksu
    Nov 8 at 10:38















up vote
0
down vote

favorite












I searched a relevant question but couldn't find one. So my question is how do I sort an array based on an arbitrary order. For example, let's say the ordering is:



order_of_elements = ['cc', 'zz', '4b', '13']


and my list to be sorted:



list_to_be_sorted = ['4b', '4b', 'zz', 'cc', '13', 'cc', 'zz']


so the result needs to be:



ordered_list = ['cc', 'cc', 'zz', 'zz', '4b', '4b', '13']


please note that the reference list(order_of_elements) describes ordering and I don't ask about sorting according to the alphabetically sorted indices of the reference list.



You can assume that order_of_elements array includes all the possible elements.



Any pseudocode is welcome.










share|improve this question
























  • Any complexity requirements?
    – Nelfeal
    Nov 8 at 9:58










  • Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
    – MGoksu
    Nov 8 at 10:38













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I searched a relevant question but couldn't find one. So my question is how do I sort an array based on an arbitrary order. For example, let's say the ordering is:



order_of_elements = ['cc', 'zz', '4b', '13']


and my list to be sorted:



list_to_be_sorted = ['4b', '4b', 'zz', 'cc', '13', 'cc', 'zz']


so the result needs to be:



ordered_list = ['cc', 'cc', 'zz', 'zz', '4b', '4b', '13']


please note that the reference list(order_of_elements) describes ordering and I don't ask about sorting according to the alphabetically sorted indices of the reference list.



You can assume that order_of_elements array includes all the possible elements.



Any pseudocode is welcome.










share|improve this question















I searched a relevant question but couldn't find one. So my question is how do I sort an array based on an arbitrary order. For example, let's say the ordering is:



order_of_elements = ['cc', 'zz', '4b', '13']


and my list to be sorted:



list_to_be_sorted = ['4b', '4b', 'zz', 'cc', '13', 'cc', 'zz']


so the result needs to be:



ordered_list = ['cc', 'cc', 'zz', 'zz', '4b', '4b', '13']


please note that the reference list(order_of_elements) describes ordering and I don't ask about sorting according to the alphabetically sorted indices of the reference list.



You can assume that order_of_elements array includes all the possible elements.



Any pseudocode is welcome.







algorithm sorting






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 10:43

























asked Nov 8 at 9:49









MGoksu

358210




358210












  • Any complexity requirements?
    – Nelfeal
    Nov 8 at 9:58










  • Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
    – MGoksu
    Nov 8 at 10:38


















  • Any complexity requirements?
    – Nelfeal
    Nov 8 at 9:58










  • Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
    – MGoksu
    Nov 8 at 10:38
















Any complexity requirements?
– Nelfeal
Nov 8 at 9:58




Any complexity requirements?
– Nelfeal
Nov 8 at 9:58












Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
– MGoksu
Nov 8 at 10:38




Actually my problem is easy so there isn't any requirement for me but I just wanted to know if there is a specific algorithm or approach for this
– MGoksu
Nov 8 at 10:38












3 Answers
3






active

oldest

votes

















up vote
2
down vote



accepted










A simple and Pythonic way to accomplish this would be to compute an index lookup table for the order_of_elements array, and use the indices as the sorting key:



order_index_table = { item: idx for idx, item in enumerate(order_of_elements) }
ordered_list = sorted(list_to_be_sorted, key=lambda x: order_index_table[x])


The table reduces order lookup to O(1) (amortized) and thus does not change the time complexity of the sort.



(Of course it does assume that all elements in list_to_be_sorted are present in order_of_elements; if this is not necessarily the case then you would need a default return value in the key lambda.)






share|improve this answer























  • I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
    – MGoksu
    Nov 8 at 10:44


















up vote
1
down vote













Since you have a limited number of possible elements, and if these elements are hashable, you can use a kind of counting sort.



Put all the elements of order_of_elements in a hashmap as keys, with counters as values. Traverse you list_to_be_sorted, incrementing the counter corresponding to the current element. To build ordered_list, go through order_of_elements and add each current element the number of times indicated by the counter of that element.



hashmap hm;
for e in order_of_elements {
hm.add(e, 0);
}

for e in list_to_be_sorted {
hm[e]++;
}

list ordered_list;
for e in order_of_elements {
list.append(e, hm[e]); // Append hm[e] copies of element e
}





share|improve this answer























  • Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
    – MGoksu
    Nov 8 at 10:51






  • 1




    Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
    – Nelfeal
    Nov 8 at 11:07




















up vote
0
down vote













Approach:




  1. create an auxiliary array which will hold the index of 'order_of_elements'


  2. sort the auxiliary array.



    2.1 re-arrange the value in the main array while sorting the auxiliary array








share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53205169%2fhow-to-order-a-list-according-to-an-arbitrary-order%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote



    accepted










    A simple and Pythonic way to accomplish this would be to compute an index lookup table for the order_of_elements array, and use the indices as the sorting key:



    order_index_table = { item: idx for idx, item in enumerate(order_of_elements) }
    ordered_list = sorted(list_to_be_sorted, key=lambda x: order_index_table[x])


    The table reduces order lookup to O(1) (amortized) and thus does not change the time complexity of the sort.



    (Of course it does assume that all elements in list_to_be_sorted are present in order_of_elements; if this is not necessarily the case then you would need a default return value in the key lambda.)






    share|improve this answer























    • I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
      – MGoksu
      Nov 8 at 10:44















    up vote
    2
    down vote



    accepted










    A simple and Pythonic way to accomplish this would be to compute an index lookup table for the order_of_elements array, and use the indices as the sorting key:



    order_index_table = { item: idx for idx, item in enumerate(order_of_elements) }
    ordered_list = sorted(list_to_be_sorted, key=lambda x: order_index_table[x])


    The table reduces order lookup to O(1) (amortized) and thus does not change the time complexity of the sort.



    (Of course it does assume that all elements in list_to_be_sorted are present in order_of_elements; if this is not necessarily the case then you would need a default return value in the key lambda.)






    share|improve this answer























    • I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
      – MGoksu
      Nov 8 at 10:44













    up vote
    2
    down vote



    accepted







    up vote
    2
    down vote



    accepted






    A simple and Pythonic way to accomplish this would be to compute an index lookup table for the order_of_elements array, and use the indices as the sorting key:



    order_index_table = { item: idx for idx, item in enumerate(order_of_elements) }
    ordered_list = sorted(list_to_be_sorted, key=lambda x: order_index_table[x])


    The table reduces order lookup to O(1) (amortized) and thus does not change the time complexity of the sort.



    (Of course it does assume that all elements in list_to_be_sorted are present in order_of_elements; if this is not necessarily the case then you would need a default return value in the key lambda.)






    share|improve this answer














    A simple and Pythonic way to accomplish this would be to compute an index lookup table for the order_of_elements array, and use the indices as the sorting key:



    order_index_table = { item: idx for idx, item in enumerate(order_of_elements) }
    ordered_list = sorted(list_to_be_sorted, key=lambda x: order_index_table[x])


    The table reduces order lookup to O(1) (amortized) and thus does not change the time complexity of the sort.



    (Of course it does assume that all elements in list_to_be_sorted are present in order_of_elements; if this is not necessarily the case then you would need a default return value in the key lambda.)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 8 at 10:39

























    answered Nov 8 at 10:00









    meowgoesthedog

    8,4383823




    8,4383823












    • I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
      – MGoksu
      Nov 8 at 10:44


















    • I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
      – MGoksu
      Nov 8 at 10:44
















    I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
    – MGoksu
    Nov 8 at 10:44




    I made that implicit assumption that order_of_elements includes all the possible elements. Thanks for pointing that out
    – MGoksu
    Nov 8 at 10:44












    up vote
    1
    down vote













    Since you have a limited number of possible elements, and if these elements are hashable, you can use a kind of counting sort.



    Put all the elements of order_of_elements in a hashmap as keys, with counters as values. Traverse you list_to_be_sorted, incrementing the counter corresponding to the current element. To build ordered_list, go through order_of_elements and add each current element the number of times indicated by the counter of that element.



    hashmap hm;
    for e in order_of_elements {
    hm.add(e, 0);
    }

    for e in list_to_be_sorted {
    hm[e]++;
    }

    list ordered_list;
    for e in order_of_elements {
    list.append(e, hm[e]); // Append hm[e] copies of element e
    }





    share|improve this answer























    • Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
      – MGoksu
      Nov 8 at 10:51






    • 1




      Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
      – Nelfeal
      Nov 8 at 11:07

















    up vote
    1
    down vote













    Since you have a limited number of possible elements, and if these elements are hashable, you can use a kind of counting sort.



    Put all the elements of order_of_elements in a hashmap as keys, with counters as values. Traverse you list_to_be_sorted, incrementing the counter corresponding to the current element. To build ordered_list, go through order_of_elements and add each current element the number of times indicated by the counter of that element.



    hashmap hm;
    for e in order_of_elements {
    hm.add(e, 0);
    }

    for e in list_to_be_sorted {
    hm[e]++;
    }

    list ordered_list;
    for e in order_of_elements {
    list.append(e, hm[e]); // Append hm[e] copies of element e
    }





    share|improve this answer























    • Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
      – MGoksu
      Nov 8 at 10:51






    • 1




      Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
      – Nelfeal
      Nov 8 at 11:07















    up vote
    1
    down vote










    up vote
    1
    down vote









    Since you have a limited number of possible elements, and if these elements are hashable, you can use a kind of counting sort.



    Put all the elements of order_of_elements in a hashmap as keys, with counters as values. Traverse you list_to_be_sorted, incrementing the counter corresponding to the current element. To build ordered_list, go through order_of_elements and add each current element the number of times indicated by the counter of that element.



    hashmap hm;
    for e in order_of_elements {
    hm.add(e, 0);
    }

    for e in list_to_be_sorted {
    hm[e]++;
    }

    list ordered_list;
    for e in order_of_elements {
    list.append(e, hm[e]); // Append hm[e] copies of element e
    }





    share|improve this answer














    Since you have a limited number of possible elements, and if these elements are hashable, you can use a kind of counting sort.



    Put all the elements of order_of_elements in a hashmap as keys, with counters as values. Traverse you list_to_be_sorted, incrementing the counter corresponding to the current element. To build ordered_list, go through order_of_elements and add each current element the number of times indicated by the counter of that element.



    hashmap hm;
    for e in order_of_elements {
    hm.add(e, 0);
    }

    for e in list_to_be_sorted {
    hm[e]++;
    }

    list ordered_list;
    for e in order_of_elements {
    list.append(e, hm[e]); // Append hm[e] copies of element e
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 8 at 10:14

























    answered Nov 8 at 10:07









    Nelfeal

    3,728621




    3,728621












    • Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
      – MGoksu
      Nov 8 at 10:51






    • 1




      Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
      – Nelfeal
      Nov 8 at 11:07




















    • Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
      – MGoksu
      Nov 8 at 10:51






    • 1




      Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
      – Nelfeal
      Nov 8 at 11:07


















    Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
    – MGoksu
    Nov 8 at 10:51




    Nice solution, thanks. Just out of curiosity, is the complexity O(n) here assuming that the append operation is O(1)?
    – MGoksu
    Nov 8 at 10:51




    1




    1




    Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
    – Nelfeal
    Nov 8 at 11:07






    Indeed it is. You traverse order_of_elements twice and list_to_be_sorted once. Hashmap insertions and lookup are of amortized constant complexity. Append (of one element) is constant on a linked-list, amortized constant on an array, and constant on a pre-sized array. So, overall, the complexity is amortized O(n), as would a usual counting-sort with hashmap would be (instead of O(n log n) for usual comparison-based sorts).
    – Nelfeal
    Nov 8 at 11:07












    up vote
    0
    down vote













    Approach:




    1. create an auxiliary array which will hold the index of 'order_of_elements'


    2. sort the auxiliary array.



      2.1 re-arrange the value in the main array while sorting the auxiliary array








    share|improve this answer

























      up vote
      0
      down vote













      Approach:




      1. create an auxiliary array which will hold the index of 'order_of_elements'


      2. sort the auxiliary array.



        2.1 re-arrange the value in the main array while sorting the auxiliary array








      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        Approach:




        1. create an auxiliary array which will hold the index of 'order_of_elements'


        2. sort the auxiliary array.



          2.1 re-arrange the value in the main array while sorting the auxiliary array








        share|improve this answer












        Approach:




        1. create an auxiliary array which will hold the index of 'order_of_elements'


        2. sort the auxiliary array.



          2.1 re-arrange the value in the main array while sorting the auxiliary array









        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 14:02









        SJC

        13




        13






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53205169%2fhow-to-order-a-list-according-to-an-arbitrary-order%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Schultheiß

            Verwaltungsgliederung Dänemarks

            Liste der Kulturdenkmale in Wilsdruff