build a new array of hash from multiple array of hashes
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
add a comment |
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
add a comment |
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
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
ruby-on-rails ruby
asked Nov 21 '18 at 17:57
jose milianojose miliano
384
384
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
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) }
add a comment |
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"}]
add a comment |
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}]
add a comment |
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).
add a comment |
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
add a comment |
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',
autoActivateHeartbeat: false,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
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) }
add a comment |
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) }
add a comment |
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) }
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) }
edited Nov 21 '18 at 18:59
answered Nov 21 '18 at 18:47
Marcin KołodziejMarcin Kołodziej
4,5101315
4,5101315
add a comment |
add a comment |
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"}]
add a comment |
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"}]
add a comment |
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"}]
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"}]
edited Nov 21 '18 at 19:35
answered Nov 21 '18 at 19:20
MrCodeXMrCodeX
315
315
add a comment |
add a comment |
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}]
add a comment |
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}]
add a comment |
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}]
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}]
edited Nov 22 '18 at 7:13
answered Nov 21 '18 at 19:46
iGianiGian
4,7842725
4,7842725
add a comment |
add a comment |
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).
add a comment |
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).
add a comment |
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).
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).
edited Nov 22 '18 at 8:53
answered Nov 22 '18 at 8:47
Cary SwovelandCary Swoveland
70.6k54167
70.6k54167
add a comment |
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Nov 22 '18 at 11:49
SG 86SG 86
4,99711829
4,99711829
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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