I have the following 2 dimension array
data = [
[5014031, nil], [5014032, nil], [5014033, 0],
[5014034, nil], [3014035, 1], [5014036, 1],
[5014037, 2], [5014038, nil], [5014039, 2],
[5014040, nil], [2014041, nil], [3014042, 2]
]
When I know the value of the 1st integer of one of these arrays e.g. 5014034, what would be the most efficient way to gain the next integer value where the 2nd element matches to nil? (e.g. I would expect 5014038 to be returned)
Thanks Scott
CodePudding user response:
Simple way, using #drop_while and #find_index:
data = [
[5014031, nil], [5014032, nil], [5014033, 0],
[5014034, nil], [5014035, 1], [5014036, 1],
[5014037, 2], [5014038, nil], [5014039, 2],
[5014040, nil], [5014041, nil], [5014042, 2]
]
remaining_arr = data.drop_while { |arr| arr[0] != 5014034 }[1 .. -1]
next_int = remaining_arr[remaining_arr.find_index { |arr| arr[1].nil? }][0]
CodePudding user response:
You could slice the array into two when the first element in the inner array matches 5014034. Extract the second resulting array and use find to look for the inner array whose second element is nil:
arr
.slice_when { |a, _| a == 5014034 } # #<Enumerator: ...>
.to_a # [[[5014031, nil], [5014032, nil], [5014033, 0], [5014034, nil]], [[5014035, 1], [5014036, 1], [5014037, 2], [5014038, nil], [5014039, 2], [5014040, nil], [5014041, nil], [5014042, 2]]]
[1] # [[5014035, 1], [5014036, 1], [5014037, 2], [5014038, nil], [5014039, 2], [5014040, nil], [5014041, nil], [5014042, 2]]
.find { |_, b| b.nil? } # [5014038, nil]
[0] # 5014038
Notice this method chaining might fail if there's no array in arr whose first object inside matches 5014034, and/or the same for find.
CodePudding user response:
If sorted then the following might be faster
data = [
[5014031, nil], [5014032, nil], [5014033, 0],
[5014034, nil], [5014035, 1], [5014036, 1],
[5014037, 2], [5014038, nil], [5014039, 2],
[5014040, nil], [5014041, nil], [5014042, 2]
]
start_element = data.bsearch_index{ |a| a[0] >= 5014034 }
if start_element == nil || data[start_element] != 5014034
puts "not found"
else
data.slice((start_element 1)..).find { |a| a[1] == nil }[0]
end
