2

reject!Rubyハッシュには、一致するアイテムを返し、一致しないアイテムのみをハッシュに残すようなメソッドがありますか? 例えば:

planets = {'Mars' => 2, 'Jupiter' => 63, 'Saturn' => 47}

few_moons = planets.some_method! do |planet, moon_count|
  moon_count < 50
end

few_moons #=> {'Mars'  => 2, 'Saturn' => 47}
planets   #=> {'Jupiter' => 63}

reject!元のハッシュから拒否されたアイテムを差し引いたものを返します。partition近いですが、ハッシュではなくタプルの配列を返し、元のハッシュを変更しません。

ドキュメントにはこのようなものは見当たらないので、自分で作成する前に質問したかったのです。

4

5 に答える 5

4

1 つの回避策は、Proc を 2 回使用することです。

moon_filter = Proc.new {|planet, moon_count| moon_count < 50 }
few_moons   = planets.select(&moon_filter)
lotsa_moons = planets.reject(&moon_filter)
planets     = lotsa_moons
于 2012-04-17T20:08:09.253 に答える
4
few_moons, many_moons = 
  planets.partition { |planet, moon_count| moon_count < 50 } \
  .map{ |v| Hash[v] }
于 2012-04-17T20:43:06.273 に答える
2

もありますEnumerable#group_by

planets_with = planets.group_by do |planet, moon_count|
  moon_count < 50 ? :many_moons : :few_moons
end

few  = planets_with[:few_moons]
many = planets_with[:many_moons]

ただし、これはハッシュの配列ではなく、配列の配列にマップされます。それを修正するには:

planets_with.merge!(planets_with) { |key, values| Hash[values] }
于 2012-04-17T20:00:59.927 に答える
1

自分で巻いた

class Hash
  def reject_and_return!(&block)
    matches = {}
    self.each do |k, v|
      matches[k] = self.delete(k) if block.call(k, v)
    end
    matches
  end
end

期待どおりに動作します:

planets = {'Mars' => 2, 'Jupiter' => 63, 'Saturn' => 47}

few_moons = planets.reject_and_return! do |planet, moon_count|
  moon_count < 50
end

few_moons #=> {'Mars'  => 2, 'Saturn' => 47}
planets   #=> {'Jupiter' => 63}
于 2012-04-17T20:43:00.017 に答える
0

Hash[] コンストラクターは、パーティションから配列を取得し、必要な方法でハッシュに変換します。1行ではありませんが、よりクリーンだと思います:

a, not_a = {a: 'b', c: 'd', e: 'f'}.partition{|k,v| k == :a} a=ハッシュ[a] not_a = ハッシュ[not_a}

于 2012-11-05T20:56:40.920 に答える