I am trying to understand this code snippet:
while row = input.gets
row.strip!
next if row.empty?
valuesplit = row.split("---")
a, b = valuesplit[1..2]
unless a == b
$hash1[a] ||= {} <--------------What is this line doing? How is the whole loop
$hash1[a][b] = true being traversed?
if $hash1[b] && $hash1[b][a] <-----Can you please describe this if() loop
$hash2[a] ||= []
$hash2[a] << b
$hash2[b] ||= []
$hash2[b] << a
end
end
end
NOTE: $hash1 = {} $hash2 = {}
Thanks!
UPDATE
Input:
junkdata1 value1 value2
junkdata2 va开发者_C百科lue3 value4
junkdata3 value5 value6
and so on.
Updated the code lines with comments too.
# loops by reading in every line of the input
# (input can be a file or another I/O object)
# every line is stored successively in a variable
# called "row"
while row = input.gets
# removes leading and trailing whitespace from
# the string that is stored in the "row" variable
row.strip!
# if the string is empty, continue to the next
# line (go back to beginning of loop)
next if row.empty?
# split the string into an array of substrings
# based on the "---" delimiter
valuesplit = row.split("---")
# assign the second substring in the valuesplit
# array to a variable called a, and the third to
# a variable called b
a, b = valuesplit[1..2]
# if a and b are different
unless a == b
# initialize the hash1 dictionary's a entry
# to an empty sub-dictionary if it is null
$hash1[a] ||= {}
# in the hash1 dictionary, set a's entry
# to a dictionary that has b as the entry
# and true as the value
$hash1[a][b] = true
# if the value for the b entry in the hash1
# dictionary is true (not false or null) AND the value for a's
# entry of the dictionary found at the b
# entry of the hash1 dictionary is true
if $hash1[b] && $hash1[b][a]
# initialize the hash2 dictionary's a entry
# to an empty arraylist if it null or false
$hash2[a] ||= []
# add b to this arraylist
$hash2[a] << b
# initialize the hash2 dictionary's b entry
# to an empty arraylist if it null or false
$hash2[b] ||= []
# add a to this arraylist
$hash2[b] << a
end # end of the if $hash1[b]... statement
end # end of the unless a == b statement
end # end of the gets loop
I still feel the question is a little vague. You should also note that I have ignored your example data. Given your example data, the results of both $hash1 and $hash2 are empty hashes.
For your first question:
$hash1[a] ||= {}
The above is a combination of two things First is an index into a hash which I'll assume you're familiar with. The second is sort of a conditional assignment. As an example:
blah ||= 1
The above says, assign the value 1 to blah as long as blah is nil. If blah is not nil then the assignment is not performed.
For the if statement we'll need some context:
if $hash1[b] && $hash1[b][a] #if the pair exists reversed
$hash2[a] ||= [] #initialize the array for the second
$hash2[a] << b #append the third to the second's array
$hash2[b] ||= [] #likewise for the reverse
$hash2[b] << a
end
If we assume that the initial values of $hash1 and $hash2 are {} as you note, and if we assume the input are a series of --- delimted values, then given the following data set:
foo---b---c
foo---c---a
foo---a---b
foo---b---a
foo---a---d
foo---d---a
The value of $hash1 would be:
{"a"=>{"b"=>true, "d"=>true}, "b"=>{"a"=>true, "c"=>true}, "c"=>{"a"=>true}, "d"=>{"a"=>true}}
Where $hash2 would be:
{"a"=>["b", "d"], "b"=>["a"], "d"=>["a"]}
Given this, I can make an educated guess that the block of code is generating a dictionary of relationships. In the above, $hash1 lists whether a given value refers to other values. A sort of a truth test. If you wanted to know if A referred to B you could just use:
$hash1['a']['b']
If the result is true then the answer is yes.
$hash2 is a sort of dictionary of two way relationships. If you checked:
$hash2['a']
You would find an array of all the things to which A refers which also refer to A.
Cheers.
foo ||= bar
This is shorthand for
foo = foo || bar
Just like it is shorthand in Java. It basically means "set foo equal to the default of bar if foo is currently nil, otherwise leave it alone" (nil evaluates to false in ruby)
精彩评论