在Ruby中,每个和If语句的行为与我所希望的不同
在下面的代码中,我的期望是,由于第二个在Ruby中,每个和If语句的行为与我所希望的不同,ruby,arrays,if-statement,hash,break,Ruby,Arrays,If Statement,Hash,Break,在下面的代码中,我的期望是,由于第二个elsif语句,将:key2或:key5分配给“1”,但是似乎我的代码运行的是最后的else语句。我的break语句是否未放置在正确的位置 每当运行此代码时,我只希望它替换一个值并结束 hash = { :key1 => "3", :key2 => "3", :key3 => "3", :key4 => "3", :key5 => "3", :key6 => "3", :key7 => "3", :key8 =>
elsif
语句,将:key2
或:key5
分配给“1”
,但是似乎我的代码运行的是最后的else
语句。我的break
语句是否未放置在正确的位置
每当运行此代码时,我只希望它替换一个值并结束
hash = { :key1 => "3", :key2 => "3", :key3 => "3", :key4 => "3", :key5 => "3", :key6 => "3", :key7 => "3", :key8 => "2", :key9 => "3"}
array = [[:key1, :key2, :key3], [:key4, :key5, :key6], [:key7, :key8, :key9], [:key1, :key4, :key7], [:key2, :key5, :key8],[:key3, :key6, :key9], [:key1, :key5, :key9], [:key3, :key5, :key7]]
array.each do |x|
if hash.values_at(*x).count("1") == 2 and hash.values_at(*x).count("3") == 1
x.each do |x|
if hash[x] == "3"
hash[x] = "1"
break
end
end
break
elsif hash.values_at(*x).count("2") == 2 and hash.values_at(*x).count("3") == 1
x.each do |e|
if hash[e] == "3"
hash[e] = "1"
break
end
end
break
elsif hash.values_at(*x).count("1") == 1 and hash.values_at(*x).count("3") == 2
x.each do |g|
if hash[g] == "3"
hash[g] = "1"
break
end
end
break
elsif hash.values_at(*x).count("3") == 3
x.each do |h|
if hash[h] == "3"
hash[h] = "1"
break
end
end
break
else
end
end
散列中没有除
“3”
以外的值,因此除了最后一个elsif
,所有条件最初都不会成功,因为它们都要求存在除“3”
以外的值。在最后一个elsif
的主体中,您将散列[key1]
重新定义为“1”
,但随后您将从内部每个
中断开,然后从外部每个中断开,终止执行。没有其他事情发生。这是一些。。。有趣的代码。我当然建议简化以帮助调试,但下面是正在发生的事情
进入数组。每个
elsif hash.values_在(*x).count(“3”)==3
你玩了一下散列,然后爆发出来
您从数组中分离出来。每个
完成了
婴儿步和put
调用在这里是您的朋友。以下是您的代码,用更好的空格重新组织:
hash = {
:key1 => "3",
:key2 => "3",
:key3 => "3",
:key4 => "3",
:key5 => "3",
:key6 => "3",
:key7 => "3",
:key8 => "2",
:key9 => "3"
}
array = [
[:key1, :key2, :key3],
[:key4, :key5, :key6],
[:key7, :key8, :key9],
[:key1, :key4, :key7],
[:key2, :key5, :key8],
[:key3, :key6, :key9],
[:key1, :key5, :key9],
[:key3, :key5, :key7]
]
array.each do |key_set|
if hash.values_at(*key_set).count("1") == 2 and hash.values_at(*key_set).count("3") == 1
key_set.each do |x|
if hash[x] == "3"
hash[x] = "1"
break
end
end
break
elsif hash.values_at(*key_set).count("2") == 2 and hash.values_at(*key_set).count("3") == 1
key_set.each do |e|
if hash[e] == "3"
hash[e] = "1"
break
end
end
break
elsif hash.values_at(*key_set).count("1") == 1 and hash.values_at(*key_set).count("3") == 2
key_set.each do |g|
if hash[g] == "3"
hash[g] = "1"
break
end
end
break
elsif hash.values_at(*key_set).count("3") == 3
key_set.each do |h|
if hash[h] == "3"
hash[h] = "1"
break
end
end
break
else
end
end
在这里,它改进了变量名,和
替换为&&
加上一些括号,以直观地显示条件中的逻辑组:
array.each do |key_set|
case
when (hash.values_at(*key_set).count("1") == 2) && (hash.values_at(*key_set).count("3") == 1)
key_set.each do |_key|
if hash[_key] == "3"
hash[_key] = "1"
break
end
end
break
when (hash.values_at(*key_set).count("2") == 2) && (hash.values_at(*key_set).count("3") == 1)
key_set.each do |_key|
if hash[_key] == "3"
hash[_key] = "1"
break
end
end
break
when (hash.values_at(*key_set).count("1") == 1) && (hash.values_at(*key_set).count("3") == 2)
key_set.each do |_key|
if hash[_key] == "3"
hash[_key] = "1"
break
end
end
break
when (hash.values_at(*key_set).count("3") == 3)
key_set.each do |_key|
if hash[_key] == "3"
hash[_key] = "1"
break
end
end
break
else
end
end
有大量的冗余和缺乏“干燥”。“DRY”代表“不要重复你自己”,意思是减少重复的代码
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
break
看起来是对以下各项的合理替代:
key_set.each do |_key|
if hash[_key] == "3"
hash[_key] = "1"
break
end
end
break
因此,在中替换该值将代码缩减为:
array.each do |key_set|
case
when (hash.values_at(*key_set).count("1") == 2) && (hash.values_at(*key_set).count("3") == 1)
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
break
when (hash.values_at(*key_set).count("2") == 2) && (hash.values_at(*key_set).count("3") == 1)
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
break
when (hash.values_at(*key_set).count("1") == 1) && (hash.values_at(*key_set).count("3") == 2)
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
break
when (hash.values_at(*key_set).count("3") == 3)
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
break
else
end
end
当
时,每个都是冗余的,因此它们可以移动到案例的上方
:
array.each do |key_set|
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
case
when (hash.values_at(*key_set).count("1") == 2) && (hash.values_at(*key_set).count("3") == 1)
break
when (hash.values_at(*key_set).count("2") == 2) && (hash.values_at(*key_set).count("3") == 1)
break
when (hash.values_at(*key_set).count("1") == 1) && (hash.values_at(*key_set).count("3") == 2)
break
when (hash.values_at(*key_set).count("3") == 3)
break
else
end
end
puts hash
稍微减少一点会导致:
array.each do |key_set|
_key = key_set.find{ |k| hash[k] == '3' }
hash[_key] = '1' if _key
case
when (hash.values_at(*key_set).count("1") == 2) && (hash.values_at(*key_set).count("3") == 1),
(hash.values_at(*key_set).count("2") == 2) && (hash.values_at(*key_set).count("3") == 1),
(hash.values_at(*key_set).count("1") == 1) && (hash.values_at(*key_set).count("3") == 2),
(hash.values_at(*key_set).count("3") == 3)
break
else
end
end
puts hash
与所有其他产品一样,其输出:
{:key1=>"1", :key2=>"3", :key3=>"3", :key4=>"3", :key5=>"3", :key6=>"3", :key7=>"3", :key8=>"2", :key9=>"3"}
第一个程序中有很多代码要做最后一个程序所做的事情。还有,我们可以做更多的干燥工作,但我将让您自己来解决。对不起,按8键应该是“2”。然而,当我运行它时:不管怎样,key1总是设置为“1”。这仍然只会给你一个“2”,而不是条件要求的两个,因此结果是一样的。你需要看看case
语句是如何工作的。似乎您正在尝试重新设计的工作方式,使其在时的行为类似于案例
/,或者可能是嵌套的案例
语句。您还在第6行使用x来隐藏外部变量。每个do | x |
都不是真正要做的事情。案例
会按顺序运行它们吗?我基本上希望它们按顺序运行,如果其中一个键被更改为“1”,那么我希望循环中断@theTinManYes,不要隐藏变量名。对于长度可以超过一个字符的变量名,请使用一些更具描述性的名称。case
将按照与if
相同的顺序运行它们。逻辑从顶部开始,然后通过检查条件来完成。我只是在学习编码,所以我知道它不是最好的。我希望一旦我得到它的工作,我可以折射。谢谢你,我添加了一个put
到第二个when
,并将键8改为“1”,期待我的put
但是我收到了put
我包括在最后的when
中。编辑:我将检查我的代码,直到它达到最佳性能。@ravensklock-在@TimMan的简化代码中只有一个。当你说“final when”时,你指的是什么?在看了这个之后,我明白了我在哪里搞砸了,但我该怎么做,这样它会迭代所有数组键集
,最后只执行(hash.values\u at(*key\u set).count(“3”)==3)
如果没有一个阵列可以满足上述任何情况,请输入以下代码@铁皮人@petetalfivin