我正在尝试理解这段代码:
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
注意:$ hash1 = {} $ hash2 = {}
谢谢!
更新
输入:
junkdata1 value1 value2
junkdata2 value3 value4
junkdata3 value5 value6
等等。
也更新了带注释的代码行。
答案 0 :(得分:12)
# 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
答案 1 :(得分:5)
我仍然觉得这个问题有点模糊。您还应该注意我忽略了您的示例数据。给定您的示例数据,$ hash1和$ hash2的结果都是空哈希值。
关于你的第一个问题:
$hash1[a] ||= {}
以上是两件事的组合 首先是哈希的索引,我假设你很熟悉。 第二种是条件赋值。举个例子:
blah ||= 1
如上所述,只要blah为零,就将值1赋值给blah。如果blah不是nil则不执行赋值。
对于if语句,我们需要一些上下文:
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
如果我们假设$ hash1和$ hash2的初始值是{},并且如果我们假设输入是一系列---分隔值,那么给出以下数据集:
foo---b---c
foo---c---a
foo---a---b
foo---b---a
foo---a---d
foo---d---a
$ hash1的值为:
{"a"=>{"b"=>true, "d"=>true}, "b"=>{"a"=>true, "c"=>true}, "c"=>{"a"=>true}, "d"=>{"a"=>true}}
$ hash2将是:
{"a"=>["b", "d"], "b"=>["a"], "d"=>["a"]}
鉴于此,我可以做出有根据的猜测,即代码块正在生成关系字典。在上面,$ hash1列出给定值是否引用其他值。一种真理测试。如果您想知道A是否可以使用B,那么您可以使用:
$hash1['a']['b']
如果结果为真,那么答案是肯定的。
$ hash2是一种双向关系的字典。 如果您选中:
$hash2['a']
你会找到一个A引用的所有东西的数组,它也引用A。
干杯。
答案 2 :(得分:2)
foo ||= bar
这是
的简写 foo = foo || bar
就像它是Java中的简写一样。它基本上意味着“如果foo当前为零,则将foo设置为等于默认值bar,否则不要单独”(在ruby中为nil评估为false)