Reputation: 3830
I have two arrays that I need to check against each other. When a match is found I need to unset the value from the first array and push that value to a new array.
Here is an example:
First Array import_data
["mario", "blue", "SGC", "CJ672PA0"],
["solid snake", "green", "NID", "VI6965KD"],
["samus", "maroon", "TRUST", "DNYU6539"],
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]
Second Array current_data
["gordon", "orange", "DRONE", "OGJR8C0D"],
["samus", "black", "TRUST", "DNYU6539"],
["commander shepard", "red", "WHX", "TH985OI3"]
Notice that "samus" appears in both arrays with all the same data but a change to the color.
My intent is to loop through import_data
and check the last index of each item in the array (the 8-digit "id") and compare that against current_data
. Each time a "match" is found (based on the 8-digit "id") I want to push that item into a new array update_data
and then I want to unset
that match in the import_data
array.
The problem is that both arrays are of differing lengths. So as soon as my loop goes beyond the length of one item it can no longer check that index which results in an error.
My code essentially looks like this:
import_data.each_with_index do |data, index|
if data[3] == current_data[index].id
# @update_data << somehow push all of the data
end
end
The reason this isn't working is because the length of import_data
is longer than that of current_data
. This results in the error:
"undefined method `id' for nil:NilClass"
Ideally the end result would be as follows:
"samus" has been removed from the import_data
array and pushed to the update_data
array
import_data
array after loop
["mario", "blue", "SGC", "CJ672PA0"],
["solid snake", "green", "NID", "VI6965KD"],
---
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]
Newly populated array update_data
["samus", "maroon", "TRUST", "DNYU6539"]
Upvotes: 1
Views: 1437
Reputation: 5229
Since the answer of Prakash works, I think this is more straightforward:
import_data = [
["mario", "blue", "SGC", "CJ672PA0"],
["solid snake", "green", "NID", "VI6965KD"],
["samus", "maroon", "TRUST", "DNYU6539"],
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]
]
current_data = [
["gordon", "orange", "DRONE", "OGJR8C0D"],
["samus", "black", "TRUST", "DNYU6539"],
["commander shepard", "red", "WHX", "TH985OI3"]
]
current_ids = current_data.map {|c| c[3]}
update_data = import_data.inject([]) do |result, data|
result << import_data.delete(data) if current_ids.include?(data[3])
result
end
After run you get:
update_data = [
["samus", "maroon", "TRUST", "DNYU6539"]
]
import_data = [
["mario", "blue", "SGC", "CJ672PA0"],
["solid snake", "green", "NID", "VI6965KD"],
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]
]
I hope it helps.
Upvotes: 3
Reputation: 13067
One way to accomplish what you are doing:
import_data = [
["mario", "blue", "SGC", "CJ672PA0"],
["solid snake", "green", "NID", "VI6965KD"],
["samus", "maroon", "TRUST", "DNYU6539"],
["deckard cain", "purple", "JAFA", "SJW252MZ"],
["wedge", "yellow", "WALTER", "UJ28NVM1"]
]
current_data = [
["gordon", "orange", "DRONE", "OGJR8C0D"],
["samus", "black", "TRUST", "DNYU6539"],
["commander shepard", "red", "WHX", "TH985OI3"]
]
Find the keys for both the arrays:
import_data_keys = import_data.map { |x| x[3] }
=> ["CJ672PA0", "VI6965KD", "DNYU6539", "SJW252MZ", "UJ28NVM1"]
current_data_keys = current_data.map { |x| x[3] }
=> ["OGJR8C0D", "DNYU6539", "TH985OI3"]
Find the common keys by intersecting these two arrays:
common_keys = import_data_keys & current_data_keys
=> ["DNYU6539"]
Use common_keys
to delete from import_data
and push to update_data
.
common_keys.each do |key|
import_data.each_with_index do |data, index|
if data[3] == key
update_data << import_data[index]
import_data.delete_at(index)
break
end
end
end
Note: The break
statement is for stopping with that iteration after the element is found and processed.
Upvotes: 1