build a new array of hash from multiple array of hashes











up vote
0
down vote

favorite












I have following three array of hashes.



customer_mapping = [
{:customer_id=>"a", :customer_order_id=>"g1"},
{:customer_id=>"b", :customer_order_id=>"g2"},
{:customer_id=>"c", :customer_order_id=>"g3"},
{:customer_id=>"d", :customer_order_id=>"g4"},
{:customer_id=>"e", :customer_order_id=>"g5"}
]

customer_with_products = [
{:customer_order_id=>"g1", :product_order_id=>"a1"},
{:customer_order_id=>"g2", :product_order_id=>"a2"},
{:customer_order_id=>"g3", :product_order_id=>"a3"},
{:customer_order_id=>"g4", :product_order_id=>"a4"},
{:customer_order_id=>"g5", :product_order_id=>"a5"}
]

product_mapping = [
{:product_id=>"j", :product_order_id=>"a1"},
{:product_id=>"k", :product_order_id=>"a2"},
{:product_id=>"l", :product_order_id=>"a3"}
]


What i want is a new hash with only customer_id and product_id



{:product_id=>"j", :customer_id=>"a"},
{:product_id=>"k", :customer_id=>"b"},
{:product_id=>"l", :customer_id=>"c"}


I tried to loop over product_mapping and select the customer_order_id that match product_order_id in customer_with_products and then thought of looping over customer_mapping but not able to get desired output from the first step.



How can i achieve this?










share|improve this question







New contributor




jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    0
    down vote

    favorite












    I have following three array of hashes.



    customer_mapping = [
    {:customer_id=>"a", :customer_order_id=>"g1"},
    {:customer_id=>"b", :customer_order_id=>"g2"},
    {:customer_id=>"c", :customer_order_id=>"g3"},
    {:customer_id=>"d", :customer_order_id=>"g4"},
    {:customer_id=>"e", :customer_order_id=>"g5"}
    ]

    customer_with_products = [
    {:customer_order_id=>"g1", :product_order_id=>"a1"},
    {:customer_order_id=>"g2", :product_order_id=>"a2"},
    {:customer_order_id=>"g3", :product_order_id=>"a3"},
    {:customer_order_id=>"g4", :product_order_id=>"a4"},
    {:customer_order_id=>"g5", :product_order_id=>"a5"}
    ]

    product_mapping = [
    {:product_id=>"j", :product_order_id=>"a1"},
    {:product_id=>"k", :product_order_id=>"a2"},
    {:product_id=>"l", :product_order_id=>"a3"}
    ]


    What i want is a new hash with only customer_id and product_id



    {:product_id=>"j", :customer_id=>"a"},
    {:product_id=>"k", :customer_id=>"b"},
    {:product_id=>"l", :customer_id=>"c"}


    I tried to loop over product_mapping and select the customer_order_id that match product_order_id in customer_with_products and then thought of looping over customer_mapping but not able to get desired output from the first step.



    How can i achieve this?










    share|improve this question







    New contributor




    jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have following three array of hashes.



      customer_mapping = [
      {:customer_id=>"a", :customer_order_id=>"g1"},
      {:customer_id=>"b", :customer_order_id=>"g2"},
      {:customer_id=>"c", :customer_order_id=>"g3"},
      {:customer_id=>"d", :customer_order_id=>"g4"},
      {:customer_id=>"e", :customer_order_id=>"g5"}
      ]

      customer_with_products = [
      {:customer_order_id=>"g1", :product_order_id=>"a1"},
      {:customer_order_id=>"g2", :product_order_id=>"a2"},
      {:customer_order_id=>"g3", :product_order_id=>"a3"},
      {:customer_order_id=>"g4", :product_order_id=>"a4"},
      {:customer_order_id=>"g5", :product_order_id=>"a5"}
      ]

      product_mapping = [
      {:product_id=>"j", :product_order_id=>"a1"},
      {:product_id=>"k", :product_order_id=>"a2"},
      {:product_id=>"l", :product_order_id=>"a3"}
      ]


      What i want is a new hash with only customer_id and product_id



      {:product_id=>"j", :customer_id=>"a"},
      {:product_id=>"k", :customer_id=>"b"},
      {:product_id=>"l", :customer_id=>"c"}


      I tried to loop over product_mapping and select the customer_order_id that match product_order_id in customer_with_products and then thought of looping over customer_mapping but not able to get desired output from the first step.



      How can i achieve this?










      share|improve this question







      New contributor




      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I have following three array of hashes.



      customer_mapping = [
      {:customer_id=>"a", :customer_order_id=>"g1"},
      {:customer_id=>"b", :customer_order_id=>"g2"},
      {:customer_id=>"c", :customer_order_id=>"g3"},
      {:customer_id=>"d", :customer_order_id=>"g4"},
      {:customer_id=>"e", :customer_order_id=>"g5"}
      ]

      customer_with_products = [
      {:customer_order_id=>"g1", :product_order_id=>"a1"},
      {:customer_order_id=>"g2", :product_order_id=>"a2"},
      {:customer_order_id=>"g3", :product_order_id=>"a3"},
      {:customer_order_id=>"g4", :product_order_id=>"a4"},
      {:customer_order_id=>"g5", :product_order_id=>"a5"}
      ]

      product_mapping = [
      {:product_id=>"j", :product_order_id=>"a1"},
      {:product_id=>"k", :product_order_id=>"a2"},
      {:product_id=>"l", :product_order_id=>"a3"}
      ]


      What i want is a new hash with only customer_id and product_id



      {:product_id=>"j", :customer_id=>"a"},
      {:product_id=>"k", :customer_id=>"b"},
      {:product_id=>"l", :customer_id=>"c"}


      I tried to loop over product_mapping and select the customer_order_id that match product_order_id in customer_with_products and then thought of looping over customer_mapping but not able to get desired output from the first step.



      How can i achieve this?







      ruby-on-rails ruby






      share|improve this question







      New contributor




      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 2 days ago









      jose miliano

      41




      41




      New contributor




      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      jose miliano is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.
























          6 Answers
          6






          active

          oldest

          votes

















          up vote
          2
          down vote













          Using



          def merge_by(a,b, key)
          (a+b).group_by { |h| h[key] }
          .each_value.map { |arr| arr.inject(:merge) }
          end

          merge_by(
          merge_by(customer_mapping, customer_with_products, :customer_order_id),
          product_mapping,
          :product_order_id
          ).select { |h| h[:product_id] }.map { |h| h.slice(:product_id, :customer_id) }

          #=>[{:product_id=>"j", :customer_id=>"a"},
          # {:product_id=>"k", :customer_id=>"b"},
          # {:product_id=>"l", :customer_id=>"c"}]


          Definitely not the cleanest solution, if your initial arrays come from SQL queries, I think those queries could be modified to aggregate your data properly.



          merge_by(customer_mapping, customer_with_products, :customer_order_id)
          # => [{:customer_id=>"a", :customer_order_id=>"g1", :product_order_id=>"a1"},
          # {:customer_id=>"b", :customer_order_id=>"g2", :product_order_id=>"a2"},
          # {:customer_id=>"c", :customer_order_id=>"g3", :product_order_id=>"a3"},
          # {:customer_id=>"d", :customer_order_id=>"g4", :product_order_id=>"a4"},
          # {:customer_id=>"e", :customer_order_id=>"g5", :product_order_id=>"a5"}]


          Then merge it similarly with your last array and cleanup the result selecting only the elements for which :product_id was found, slicing wanted keys.



          Alternatively, a much more readable solution, depending on your array sizes might be slower as it keeps iterating over the hashes:



          product_mapping.map do |hc| 
          b_match = customer_with_products.detect { |hb| hb[:product_order_id] == hc[:product_order_id] }
          a_match = customer_mapping.detect { |ha| ha[:customer_order_id] == b_match[:customer_order_id] }
          [hc, a_match, b_match].inject(:merge)
          end.map { |h| h.slice(:product_id, :customer_id) }





          share|improve this answer






























            up vote
            1
            down vote













            Following your handling of the problem the solution would be the following:



            result_hash_array = product_mapping.map do |product_mapping_entry|
            customer_receipt = customer_with_products.find do |customer_with_products_entry|
            product_mapping_entry[:product_order_id] == customer_with_products_entry[:product_order_id]
            end
            customer_id = customer_mapping.find do |customer_mapping_entry|
            customer_receipt[:customer_order_id] == customer_mapping_entry[:customer_order_id]
            end[:customer_id]
            {product_id: product_mapping_entry[:product_id], customer_id: customer_id}
            end


            Output



            results_hash_array => [{:product_id=>"j", :customer_id=>"a"},
            {:product_id=>"k", :customer_id=>"b"},
            {:product_id=>"l", :customer_id=>"c"}]





            share|improve this answer






























              up vote
              0
              down vote













              Using map and find.



              customer_mapping.map do |cm|
              cp = customer_with_products.find {|cp| cp[:customer_order_id] == cm[:customer_order_id] }
              pm = product_mapping.find {|pm| pm[:product_order_id] == cp&.(:product_order_id)}
              pm ? {customer_id: cm[:customer_id], product_id: pm[:product_id]} : nil
              end.compact
              # => [{:customer_id=>"a", :product_id=>"j"},
              # {:customer_id=>"b", :product_id=>"k"},
              # {:customer_id=>"c", :product_id=>"l"}]





              share|improve this answer




























                up vote
                0
                down vote













                Other option, starting from customer_mapping, one liner (but quite wide):



                customer_mapping.map { |e| {customer_id: e[:customer_id], product_id: (product_mapping.detect { |k| k[:product_order_id] == (customer_with_products.detect{ |h| h[:customer_order_id] == e[:customer_order_id] } || {} )[:product_order_id] } || {} )[:product_id]  } }

                #=> [{:customer_id=>"a", :product_id=>"j"},
                # {:customer_id=>"b", :product_id=>"k"},
                # {:customer_id=>"c", :product_id=>"l"},
                # {:customer_id=>"d", :product_id=>nil},
                # {:customer_id=>"e", :product_id=>nil}]





                share|improve this answer






























                  up vote
                  0
                  down vote













                  cust_order_id_to_cust_id =
                  customer_mapping.each_with_object({}) do |g,h|
                  h[g[:customer_order_id]] = g[:customer_id]
                  end
                  #=> {"g1"=>"a", "g2"=>"b", "g3"=>"c", "g4"=>"d", "g5"=>"e"}

                  prod_order_id_to_cust_order_id =
                  customer_with_products.each_with_object({}) do |g,h|
                  h[g[:product_order_id]] = g[:customer_order_id]
                  end
                  #=> {"a1"=>"g1", "a2"=>"g2", "a3"=>"g3", "a4"=>"g4", "a5"=>"g5"}

                  product_mapping.map do |h|
                  { product_id: h[:product_id], customer_id:
                  cust_order_id_to_cust_id[prod_order_id_to_cust_order_id[h[:product_order_id]]] }
                  end
                  #=> [{:product_id=>"j", :customer_id=>"a"},
                  # {:product_id=>"k", :customer_id=>"b"},
                  # {:product_id=>"l", :customer_id=>"c"}]


                  This formulation is particularly easy to test. (It's so straightforward that no debugging was needed).






                  share|improve this answer






























                    up vote
                    0
                    down vote













                    I would recommended to rather take a longer but more readable solution which you also understand in some months from now by looking at it. Use full names for the hash keys instead of hiding them behind k, v for more complexe lookups (maybe its just my personal preference).



                    I would suggest somethink like:



                    result = product_mapping.map do |mapping|
                    customer_id = customer_mapping.find do |hash|
                    hash[:customer_order_id] == customer_with_products.find do |hash|
                    hash[:product_order_id] == mapping[:product_order_id]
                    end[:customer_order_id]
                    end[:customer_id]

                    { product_id: mapping[:product_id], customer_id: customer_id }
                    end





                    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
                      });


                      }
                      });






                      jose miliano is a new contributor. Be nice, and check out our Code of Conduct.










                       

                      draft saved


                      draft discarded


















                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418008%2fbuild-a-new-array-of-hash-from-multiple-array-of-hashes%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown

























                      6 Answers
                      6






                      active

                      oldest

                      votes








                      6 Answers
                      6






                      active

                      oldest

                      votes









                      active

                      oldest

                      votes






                      active

                      oldest

                      votes








                      up vote
                      2
                      down vote













                      Using



                      def merge_by(a,b, key)
                      (a+b).group_by { |h| h[key] }
                      .each_value.map { |arr| arr.inject(:merge) }
                      end

                      merge_by(
                      merge_by(customer_mapping, customer_with_products, :customer_order_id),
                      product_mapping,
                      :product_order_id
                      ).select { |h| h[:product_id] }.map { |h| h.slice(:product_id, :customer_id) }

                      #=>[{:product_id=>"j", :customer_id=>"a"},
                      # {:product_id=>"k", :customer_id=>"b"},
                      # {:product_id=>"l", :customer_id=>"c"}]


                      Definitely not the cleanest solution, if your initial arrays come from SQL queries, I think those queries could be modified to aggregate your data properly.



                      merge_by(customer_mapping, customer_with_products, :customer_order_id)
                      # => [{:customer_id=>"a", :customer_order_id=>"g1", :product_order_id=>"a1"},
                      # {:customer_id=>"b", :customer_order_id=>"g2", :product_order_id=>"a2"},
                      # {:customer_id=>"c", :customer_order_id=>"g3", :product_order_id=>"a3"},
                      # {:customer_id=>"d", :customer_order_id=>"g4", :product_order_id=>"a4"},
                      # {:customer_id=>"e", :customer_order_id=>"g5", :product_order_id=>"a5"}]


                      Then merge it similarly with your last array and cleanup the result selecting only the elements for which :product_id was found, slicing wanted keys.



                      Alternatively, a much more readable solution, depending on your array sizes might be slower as it keeps iterating over the hashes:



                      product_mapping.map do |hc| 
                      b_match = customer_with_products.detect { |hb| hb[:product_order_id] == hc[:product_order_id] }
                      a_match = customer_mapping.detect { |ha| ha[:customer_order_id] == b_match[:customer_order_id] }
                      [hc, a_match, b_match].inject(:merge)
                      end.map { |h| h.slice(:product_id, :customer_id) }





                      share|improve this answer



























                        up vote
                        2
                        down vote













                        Using



                        def merge_by(a,b, key)
                        (a+b).group_by { |h| h[key] }
                        .each_value.map { |arr| arr.inject(:merge) }
                        end

                        merge_by(
                        merge_by(customer_mapping, customer_with_products, :customer_order_id),
                        product_mapping,
                        :product_order_id
                        ).select { |h| h[:product_id] }.map { |h| h.slice(:product_id, :customer_id) }

                        #=>[{:product_id=>"j", :customer_id=>"a"},
                        # {:product_id=>"k", :customer_id=>"b"},
                        # {:product_id=>"l", :customer_id=>"c"}]


                        Definitely not the cleanest solution, if your initial arrays come from SQL queries, I think those queries could be modified to aggregate your data properly.



                        merge_by(customer_mapping, customer_with_products, :customer_order_id)
                        # => [{:customer_id=>"a", :customer_order_id=>"g1", :product_order_id=>"a1"},
                        # {:customer_id=>"b", :customer_order_id=>"g2", :product_order_id=>"a2"},
                        # {:customer_id=>"c", :customer_order_id=>"g3", :product_order_id=>"a3"},
                        # {:customer_id=>"d", :customer_order_id=>"g4", :product_order_id=>"a4"},
                        # {:customer_id=>"e", :customer_order_id=>"g5", :product_order_id=>"a5"}]


                        Then merge it similarly with your last array and cleanup the result selecting only the elements for which :product_id was found, slicing wanted keys.



                        Alternatively, a much more readable solution, depending on your array sizes might be slower as it keeps iterating over the hashes:



                        product_mapping.map do |hc| 
                        b_match = customer_with_products.detect { |hb| hb[:product_order_id] == hc[:product_order_id] }
                        a_match = customer_mapping.detect { |ha| ha[:customer_order_id] == b_match[:customer_order_id] }
                        [hc, a_match, b_match].inject(:merge)
                        end.map { |h| h.slice(:product_id, :customer_id) }





                        share|improve this answer

























                          up vote
                          2
                          down vote










                          up vote
                          2
                          down vote









                          Using



                          def merge_by(a,b, key)
                          (a+b).group_by { |h| h[key] }
                          .each_value.map { |arr| arr.inject(:merge) }
                          end

                          merge_by(
                          merge_by(customer_mapping, customer_with_products, :customer_order_id),
                          product_mapping,
                          :product_order_id
                          ).select { |h| h[:product_id] }.map { |h| h.slice(:product_id, :customer_id) }

                          #=>[{:product_id=>"j", :customer_id=>"a"},
                          # {:product_id=>"k", :customer_id=>"b"},
                          # {:product_id=>"l", :customer_id=>"c"}]


                          Definitely not the cleanest solution, if your initial arrays come from SQL queries, I think those queries could be modified to aggregate your data properly.



                          merge_by(customer_mapping, customer_with_products, :customer_order_id)
                          # => [{:customer_id=>"a", :customer_order_id=>"g1", :product_order_id=>"a1"},
                          # {:customer_id=>"b", :customer_order_id=>"g2", :product_order_id=>"a2"},
                          # {:customer_id=>"c", :customer_order_id=>"g3", :product_order_id=>"a3"},
                          # {:customer_id=>"d", :customer_order_id=>"g4", :product_order_id=>"a4"},
                          # {:customer_id=>"e", :customer_order_id=>"g5", :product_order_id=>"a5"}]


                          Then merge it similarly with your last array and cleanup the result selecting only the elements for which :product_id was found, slicing wanted keys.



                          Alternatively, a much more readable solution, depending on your array sizes might be slower as it keeps iterating over the hashes:



                          product_mapping.map do |hc| 
                          b_match = customer_with_products.detect { |hb| hb[:product_order_id] == hc[:product_order_id] }
                          a_match = customer_mapping.detect { |ha| ha[:customer_order_id] == b_match[:customer_order_id] }
                          [hc, a_match, b_match].inject(:merge)
                          end.map { |h| h.slice(:product_id, :customer_id) }





                          share|improve this answer














                          Using



                          def merge_by(a,b, key)
                          (a+b).group_by { |h| h[key] }
                          .each_value.map { |arr| arr.inject(:merge) }
                          end

                          merge_by(
                          merge_by(customer_mapping, customer_with_products, :customer_order_id),
                          product_mapping,
                          :product_order_id
                          ).select { |h| h[:product_id] }.map { |h| h.slice(:product_id, :customer_id) }

                          #=>[{:product_id=>"j", :customer_id=>"a"},
                          # {:product_id=>"k", :customer_id=>"b"},
                          # {:product_id=>"l", :customer_id=>"c"}]


                          Definitely not the cleanest solution, if your initial arrays come from SQL queries, I think those queries could be modified to aggregate your data properly.



                          merge_by(customer_mapping, customer_with_products, :customer_order_id)
                          # => [{:customer_id=>"a", :customer_order_id=>"g1", :product_order_id=>"a1"},
                          # {:customer_id=>"b", :customer_order_id=>"g2", :product_order_id=>"a2"},
                          # {:customer_id=>"c", :customer_order_id=>"g3", :product_order_id=>"a3"},
                          # {:customer_id=>"d", :customer_order_id=>"g4", :product_order_id=>"a4"},
                          # {:customer_id=>"e", :customer_order_id=>"g5", :product_order_id=>"a5"}]


                          Then merge it similarly with your last array and cleanup the result selecting only the elements for which :product_id was found, slicing wanted keys.



                          Alternatively, a much more readable solution, depending on your array sizes might be slower as it keeps iterating over the hashes:



                          product_mapping.map do |hc| 
                          b_match = customer_with_products.detect { |hb| hb[:product_order_id] == hc[:product_order_id] }
                          a_match = customer_mapping.detect { |ha| ha[:customer_order_id] == b_match[:customer_order_id] }
                          [hc, a_match, b_match].inject(:merge)
                          end.map { |h| h.slice(:product_id, :customer_id) }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 2 days ago

























                          answered 2 days ago









                          Marcin Kołodziej

                          3,332314




                          3,332314
























                              up vote
                              1
                              down vote













                              Following your handling of the problem the solution would be the following:



                              result_hash_array = product_mapping.map do |product_mapping_entry|
                              customer_receipt = customer_with_products.find do |customer_with_products_entry|
                              product_mapping_entry[:product_order_id] == customer_with_products_entry[:product_order_id]
                              end
                              customer_id = customer_mapping.find do |customer_mapping_entry|
                              customer_receipt[:customer_order_id] == customer_mapping_entry[:customer_order_id]
                              end[:customer_id]
                              {product_id: product_mapping_entry[:product_id], customer_id: customer_id}
                              end


                              Output



                              results_hash_array => [{:product_id=>"j", :customer_id=>"a"},
                              {:product_id=>"k", :customer_id=>"b"},
                              {:product_id=>"l", :customer_id=>"c"}]





                              share|improve this answer



























                                up vote
                                1
                                down vote













                                Following your handling of the problem the solution would be the following:



                                result_hash_array = product_mapping.map do |product_mapping_entry|
                                customer_receipt = customer_with_products.find do |customer_with_products_entry|
                                product_mapping_entry[:product_order_id] == customer_with_products_entry[:product_order_id]
                                end
                                customer_id = customer_mapping.find do |customer_mapping_entry|
                                customer_receipt[:customer_order_id] == customer_mapping_entry[:customer_order_id]
                                end[:customer_id]
                                {product_id: product_mapping_entry[:product_id], customer_id: customer_id}
                                end


                                Output



                                results_hash_array => [{:product_id=>"j", :customer_id=>"a"},
                                {:product_id=>"k", :customer_id=>"b"},
                                {:product_id=>"l", :customer_id=>"c"}]





                                share|improve this answer

























                                  up vote
                                  1
                                  down vote










                                  up vote
                                  1
                                  down vote









                                  Following your handling of the problem the solution would be the following:



                                  result_hash_array = product_mapping.map do |product_mapping_entry|
                                  customer_receipt = customer_with_products.find do |customer_with_products_entry|
                                  product_mapping_entry[:product_order_id] == customer_with_products_entry[:product_order_id]
                                  end
                                  customer_id = customer_mapping.find do |customer_mapping_entry|
                                  customer_receipt[:customer_order_id] == customer_mapping_entry[:customer_order_id]
                                  end[:customer_id]
                                  {product_id: product_mapping_entry[:product_id], customer_id: customer_id}
                                  end


                                  Output



                                  results_hash_array => [{:product_id=>"j", :customer_id=>"a"},
                                  {:product_id=>"k", :customer_id=>"b"},
                                  {:product_id=>"l", :customer_id=>"c"}]





                                  share|improve this answer














                                  Following your handling of the problem the solution would be the following:



                                  result_hash_array = product_mapping.map do |product_mapping_entry|
                                  customer_receipt = customer_with_products.find do |customer_with_products_entry|
                                  product_mapping_entry[:product_order_id] == customer_with_products_entry[:product_order_id]
                                  end
                                  customer_id = customer_mapping.find do |customer_mapping_entry|
                                  customer_receipt[:customer_order_id] == customer_mapping_entry[:customer_order_id]
                                  end[:customer_id]
                                  {product_id: product_mapping_entry[:product_id], customer_id: customer_id}
                                  end


                                  Output



                                  results_hash_array => [{:product_id=>"j", :customer_id=>"a"},
                                  {:product_id=>"k", :customer_id=>"b"},
                                  {:product_id=>"l", :customer_id=>"c"}]






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited 2 days ago

























                                  answered 2 days ago









                                  MrCodeX

                                  114




                                  114






















                                      up vote
                                      0
                                      down vote













                                      Using map and find.



                                      customer_mapping.map do |cm|
                                      cp = customer_with_products.find {|cp| cp[:customer_order_id] == cm[:customer_order_id] }
                                      pm = product_mapping.find {|pm| pm[:product_order_id] == cp&.(:product_order_id)}
                                      pm ? {customer_id: cm[:customer_id], product_id: pm[:product_id]} : nil
                                      end.compact
                                      # => [{:customer_id=>"a", :product_id=>"j"},
                                      # {:customer_id=>"b", :product_id=>"k"},
                                      # {:customer_id=>"c", :product_id=>"l"}]





                                      share|improve this answer

























                                        up vote
                                        0
                                        down vote













                                        Using map and find.



                                        customer_mapping.map do |cm|
                                        cp = customer_with_products.find {|cp| cp[:customer_order_id] == cm[:customer_order_id] }
                                        pm = product_mapping.find {|pm| pm[:product_order_id] == cp&.(:product_order_id)}
                                        pm ? {customer_id: cm[:customer_id], product_id: pm[:product_id]} : nil
                                        end.compact
                                        # => [{:customer_id=>"a", :product_id=>"j"},
                                        # {:customer_id=>"b", :product_id=>"k"},
                                        # {:customer_id=>"c", :product_id=>"l"}]





                                        share|improve this answer























                                          up vote
                                          0
                                          down vote










                                          up vote
                                          0
                                          down vote









                                          Using map and find.



                                          customer_mapping.map do |cm|
                                          cp = customer_with_products.find {|cp| cp[:customer_order_id] == cm[:customer_order_id] }
                                          pm = product_mapping.find {|pm| pm[:product_order_id] == cp&.(:product_order_id)}
                                          pm ? {customer_id: cm[:customer_id], product_id: pm[:product_id]} : nil
                                          end.compact
                                          # => [{:customer_id=>"a", :product_id=>"j"},
                                          # {:customer_id=>"b", :product_id=>"k"},
                                          # {:customer_id=>"c", :product_id=>"l"}]





                                          share|improve this answer












                                          Using map and find.



                                          customer_mapping.map do |cm|
                                          cp = customer_with_products.find {|cp| cp[:customer_order_id] == cm[:customer_order_id] }
                                          pm = product_mapping.find {|pm| pm[:product_order_id] == cp&.(:product_order_id)}
                                          pm ? {customer_id: cm[:customer_id], product_id: pm[:product_id]} : nil
                                          end.compact
                                          # => [{:customer_id=>"a", :product_id=>"j"},
                                          # {:customer_id=>"b", :product_id=>"k"},
                                          # {:customer_id=>"c", :product_id=>"l"}]






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered yesterday









                                          Santhosh

                                          19.3k55166




                                          19.3k55166






















                                              up vote
                                              0
                                              down vote













                                              Other option, starting from customer_mapping, one liner (but quite wide):



                                              customer_mapping.map { |e| {customer_id: e[:customer_id], product_id: (product_mapping.detect { |k| k[:product_order_id] == (customer_with_products.detect{ |h| h[:customer_order_id] == e[:customer_order_id] } || {} )[:product_order_id] } || {} )[:product_id]  } }

                                              #=> [{:customer_id=>"a", :product_id=>"j"},
                                              # {:customer_id=>"b", :product_id=>"k"},
                                              # {:customer_id=>"c", :product_id=>"l"},
                                              # {:customer_id=>"d", :product_id=>nil},
                                              # {:customer_id=>"e", :product_id=>nil}]





                                              share|improve this answer



























                                                up vote
                                                0
                                                down vote













                                                Other option, starting from customer_mapping, one liner (but quite wide):



                                                customer_mapping.map { |e| {customer_id: e[:customer_id], product_id: (product_mapping.detect { |k| k[:product_order_id] == (customer_with_products.detect{ |h| h[:customer_order_id] == e[:customer_order_id] } || {} )[:product_order_id] } || {} )[:product_id]  } }

                                                #=> [{:customer_id=>"a", :product_id=>"j"},
                                                # {:customer_id=>"b", :product_id=>"k"},
                                                # {:customer_id=>"c", :product_id=>"l"},
                                                # {:customer_id=>"d", :product_id=>nil},
                                                # {:customer_id=>"e", :product_id=>nil}]





                                                share|improve this answer

























                                                  up vote
                                                  0
                                                  down vote










                                                  up vote
                                                  0
                                                  down vote









                                                  Other option, starting from customer_mapping, one liner (but quite wide):



                                                  customer_mapping.map { |e| {customer_id: e[:customer_id], product_id: (product_mapping.detect { |k| k[:product_order_id] == (customer_with_products.detect{ |h| h[:customer_order_id] == e[:customer_order_id] } || {} )[:product_order_id] } || {} )[:product_id]  } }

                                                  #=> [{:customer_id=>"a", :product_id=>"j"},
                                                  # {:customer_id=>"b", :product_id=>"k"},
                                                  # {:customer_id=>"c", :product_id=>"l"},
                                                  # {:customer_id=>"d", :product_id=>nil},
                                                  # {:customer_id=>"e", :product_id=>nil}]





                                                  share|improve this answer














                                                  Other option, starting from customer_mapping, one liner (but quite wide):



                                                  customer_mapping.map { |e| {customer_id: e[:customer_id], product_id: (product_mapping.detect { |k| k[:product_order_id] == (customer_with_products.detect{ |h| h[:customer_order_id] == e[:customer_order_id] } || {} )[:product_order_id] } || {} )[:product_id]  } }

                                                  #=> [{:customer_id=>"a", :product_id=>"j"},
                                                  # {:customer_id=>"b", :product_id=>"k"},
                                                  # {:customer_id=>"c", :product_id=>"l"},
                                                  # {:customer_id=>"d", :product_id=>nil},
                                                  # {:customer_id=>"e", :product_id=>nil}]






                                                  share|improve this answer














                                                  share|improve this answer



                                                  share|improve this answer








                                                  edited yesterday

























                                                  answered 2 days ago









                                                  iGian

                                                  2,5142620




                                                  2,5142620






















                                                      up vote
                                                      0
                                                      down vote













                                                      cust_order_id_to_cust_id =
                                                      customer_mapping.each_with_object({}) do |g,h|
                                                      h[g[:customer_order_id]] = g[:customer_id]
                                                      end
                                                      #=> {"g1"=>"a", "g2"=>"b", "g3"=>"c", "g4"=>"d", "g5"=>"e"}

                                                      prod_order_id_to_cust_order_id =
                                                      customer_with_products.each_with_object({}) do |g,h|
                                                      h[g[:product_order_id]] = g[:customer_order_id]
                                                      end
                                                      #=> {"a1"=>"g1", "a2"=>"g2", "a3"=>"g3", "a4"=>"g4", "a5"=>"g5"}

                                                      product_mapping.map do |h|
                                                      { product_id: h[:product_id], customer_id:
                                                      cust_order_id_to_cust_id[prod_order_id_to_cust_order_id[h[:product_order_id]]] }
                                                      end
                                                      #=> [{:product_id=>"j", :customer_id=>"a"},
                                                      # {:product_id=>"k", :customer_id=>"b"},
                                                      # {:product_id=>"l", :customer_id=>"c"}]


                                                      This formulation is particularly easy to test. (It's so straightforward that no debugging was needed).






                                                      share|improve this answer



























                                                        up vote
                                                        0
                                                        down vote













                                                        cust_order_id_to_cust_id =
                                                        customer_mapping.each_with_object({}) do |g,h|
                                                        h[g[:customer_order_id]] = g[:customer_id]
                                                        end
                                                        #=> {"g1"=>"a", "g2"=>"b", "g3"=>"c", "g4"=>"d", "g5"=>"e"}

                                                        prod_order_id_to_cust_order_id =
                                                        customer_with_products.each_with_object({}) do |g,h|
                                                        h[g[:product_order_id]] = g[:customer_order_id]
                                                        end
                                                        #=> {"a1"=>"g1", "a2"=>"g2", "a3"=>"g3", "a4"=>"g4", "a5"=>"g5"}

                                                        product_mapping.map do |h|
                                                        { product_id: h[:product_id], customer_id:
                                                        cust_order_id_to_cust_id[prod_order_id_to_cust_order_id[h[:product_order_id]]] }
                                                        end
                                                        #=> [{:product_id=>"j", :customer_id=>"a"},
                                                        # {:product_id=>"k", :customer_id=>"b"},
                                                        # {:product_id=>"l", :customer_id=>"c"}]


                                                        This formulation is particularly easy to test. (It's so straightforward that no debugging was needed).






                                                        share|improve this answer

























                                                          up vote
                                                          0
                                                          down vote










                                                          up vote
                                                          0
                                                          down vote









                                                          cust_order_id_to_cust_id =
                                                          customer_mapping.each_with_object({}) do |g,h|
                                                          h[g[:customer_order_id]] = g[:customer_id]
                                                          end
                                                          #=> {"g1"=>"a", "g2"=>"b", "g3"=>"c", "g4"=>"d", "g5"=>"e"}

                                                          prod_order_id_to_cust_order_id =
                                                          customer_with_products.each_with_object({}) do |g,h|
                                                          h[g[:product_order_id]] = g[:customer_order_id]
                                                          end
                                                          #=> {"a1"=>"g1", "a2"=>"g2", "a3"=>"g3", "a4"=>"g4", "a5"=>"g5"}

                                                          product_mapping.map do |h|
                                                          { product_id: h[:product_id], customer_id:
                                                          cust_order_id_to_cust_id[prod_order_id_to_cust_order_id[h[:product_order_id]]] }
                                                          end
                                                          #=> [{:product_id=>"j", :customer_id=>"a"},
                                                          # {:product_id=>"k", :customer_id=>"b"},
                                                          # {:product_id=>"l", :customer_id=>"c"}]


                                                          This formulation is particularly easy to test. (It's so straightforward that no debugging was needed).






                                                          share|improve this answer














                                                          cust_order_id_to_cust_id =
                                                          customer_mapping.each_with_object({}) do |g,h|
                                                          h[g[:customer_order_id]] = g[:customer_id]
                                                          end
                                                          #=> {"g1"=>"a", "g2"=>"b", "g3"=>"c", "g4"=>"d", "g5"=>"e"}

                                                          prod_order_id_to_cust_order_id =
                                                          customer_with_products.each_with_object({}) do |g,h|
                                                          h[g[:product_order_id]] = g[:customer_order_id]
                                                          end
                                                          #=> {"a1"=>"g1", "a2"=>"g2", "a3"=>"g3", "a4"=>"g4", "a5"=>"g5"}

                                                          product_mapping.map do |h|
                                                          { product_id: h[:product_id], customer_id:
                                                          cust_order_id_to_cust_id[prod_order_id_to_cust_order_id[h[:product_order_id]]] }
                                                          end
                                                          #=> [{:product_id=>"j", :customer_id=>"a"},
                                                          # {:product_id=>"k", :customer_id=>"b"},
                                                          # {:product_id=>"l", :customer_id=>"c"}]


                                                          This formulation is particularly easy to test. (It's so straightforward that no debugging was needed).







                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited yesterday

























                                                          answered yesterday









                                                          Cary Swoveland

                                                          66.4k53865




                                                          66.4k53865






















                                                              up vote
                                                              0
                                                              down vote













                                                              I would recommended to rather take a longer but more readable solution which you also understand in some months from now by looking at it. Use full names for the hash keys instead of hiding them behind k, v for more complexe lookups (maybe its just my personal preference).



                                                              I would suggest somethink like:



                                                              result = product_mapping.map do |mapping|
                                                              customer_id = customer_mapping.find do |hash|
                                                              hash[:customer_order_id] == customer_with_products.find do |hash|
                                                              hash[:product_order_id] == mapping[:product_order_id]
                                                              end[:customer_order_id]
                                                              end[:customer_id]

                                                              { product_id: mapping[:product_id], customer_id: customer_id }
                                                              end





                                                              share|improve this answer

























                                                                up vote
                                                                0
                                                                down vote













                                                                I would recommended to rather take a longer but more readable solution which you also understand in some months from now by looking at it. Use full names for the hash keys instead of hiding them behind k, v for more complexe lookups (maybe its just my personal preference).



                                                                I would suggest somethink like:



                                                                result = product_mapping.map do |mapping|
                                                                customer_id = customer_mapping.find do |hash|
                                                                hash[:customer_order_id] == customer_with_products.find do |hash|
                                                                hash[:product_order_id] == mapping[:product_order_id]
                                                                end[:customer_order_id]
                                                                end[:customer_id]

                                                                { product_id: mapping[:product_id], customer_id: customer_id }
                                                                end





                                                                share|improve this answer























                                                                  up vote
                                                                  0
                                                                  down vote










                                                                  up vote
                                                                  0
                                                                  down vote









                                                                  I would recommended to rather take a longer but more readable solution which you also understand in some months from now by looking at it. Use full names for the hash keys instead of hiding them behind k, v for more complexe lookups (maybe its just my personal preference).



                                                                  I would suggest somethink like:



                                                                  result = product_mapping.map do |mapping|
                                                                  customer_id = customer_mapping.find do |hash|
                                                                  hash[:customer_order_id] == customer_with_products.find do |hash|
                                                                  hash[:product_order_id] == mapping[:product_order_id]
                                                                  end[:customer_order_id]
                                                                  end[:customer_id]

                                                                  { product_id: mapping[:product_id], customer_id: customer_id }
                                                                  end





                                                                  share|improve this answer












                                                                  I would recommended to rather take a longer but more readable solution which you also understand in some months from now by looking at it. Use full names for the hash keys instead of hiding them behind k, v for more complexe lookups (maybe its just my personal preference).



                                                                  I would suggest somethink like:



                                                                  result = product_mapping.map do |mapping|
                                                                  customer_id = customer_mapping.find do |hash|
                                                                  hash[:customer_order_id] == customer_with_products.find do |hash|
                                                                  hash[:product_order_id] == mapping[:product_order_id]
                                                                  end[:customer_order_id]
                                                                  end[:customer_id]

                                                                  { product_id: mapping[:product_id], customer_id: customer_id }
                                                                  end






                                                                  share|improve this answer












                                                                  share|improve this answer



                                                                  share|improve this answer










                                                                  answered yesterday









                                                                  SG 86

                                                                  4,85711829




                                                                  4,85711829






















                                                                      jose miliano is a new contributor. Be nice, and check out our Code of Conduct.










                                                                       

                                                                      draft saved


                                                                      draft discarded


















                                                                      jose miliano is a new contributor. Be nice, and check out our Code of Conduct.













                                                                      jose miliano is a new contributor. Be nice, and check out our Code of Conduct.












                                                                      jose miliano is a new contributor. Be nice, and check out our Code of Conduct.















                                                                       


                                                                      draft saved


                                                                      draft discarded














                                                                      StackExchange.ready(
                                                                      function () {
                                                                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53418008%2fbuild-a-new-array-of-hash-from-multiple-array-of-hashes%23new-answer', 'question_page');
                                                                      }
                                                                      );

                                                                      Post as a guest















                                                                      Required, but never shown





















































                                                                      Required, but never shown














                                                                      Required, but never shown












                                                                      Required, but never shown







                                                                      Required, but never shown

































                                                                      Required, but never shown














                                                                      Required, but never shown












                                                                      Required, but never shown







                                                                      Required, but never shown







                                                                      Popular posts from this blog

                                                                      What visual should I use to simply compare current year value vs last year in Power BI desktop

                                                                      How to ignore python UserWarning in pytest?

                                                                      Alexandru Averescu