0

次のコードでは、2 番目のステートメントが原因で:key2or:key5が割り当てられることを期待していますが、私のコードは代わりに最後のステートメントを実行しているようです。ステートメントが正しい場所に配置されていませんか?"1"elsifelsebreak

このコードが実行されるたびに、1 つの値を置き換えて終了するだけです。

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
4

3 に答える 3

1

より良い空白で再編成されたコードは次のとおりです。

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

そして、ここでは変数名が改善され、条件の論理グループを視覚的に示すためにいくつかの括弧にand置き換えられています。&&

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

大量の冗長性と「DRYness」の欠如があります。「DRY」は「Don't Repeat Yourself」の略で、繰り返しの多いコードを減らすことを意味します。

_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

これを in に置き換えると、コードは次のようになります。

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

それぞれwhenが冗長であるため、上に移動できますcase

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"}

これは、最後のコードが行うことを最初のコードで行うための大量のコードです。さらに、実行できる DRYing は他にもありますが、それを理解するのはあなたに任せます。

于 2013-10-04T23:05:23.370 に答える
0

それはいくつか... 興味深いコードです。デバッグを容易にするために単純化することを強くお勧めしますが、実際には次のようになります。

  1. 入りますarray.each
  2. elsif hash.values_at(*x).count("3") == 3ヒット
  3. あなたはハッシュで少し遊んで、抜け出します
  4. あなたは抜け出すarray.each
  5. 終わり。

ここでは、ベイビーステップとputsコールがあなたの味方です。

于 2013-10-04T22:34:49.433 に答える