rails delete array ruby hash subset contain

delete - ruby slice array



Ruby Hash cheque es subconjunto? (5)

¿Cómo puedo saber si un hash de Ruby es un subconjunto de (o incluye) otro hash?

Por ejemplo:

hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7} hash.include_hash?({}) # true hash.include_hash?({f: 6, c: 3}) # true hash.include_hash?({f: 6, c: 1}) # false


¿Podría convertir los hashes en sets y realizar la comprobación utilizando el subset? métodos subset? y superset? (o sus respectivos alias <= y >= ):

require ''set'' hash.to_set.superset?({}.to_set) # => true hash.to_set >= {a: 1}.to_set # => true {a: 2}.to_set <= hash.to_set # => false

Actualización : un punto de referencia de las soluciones propuestas:

require ''fruity'' require ''set'' hash = (''aa''..''zz'').zip(''aa''..''zz'').to_h # {"aa"=>"aa", "ab"=>"ab", ... find = (''aa''..''zz'').zip(''aa''..''zz'').select { |k, _| k[0] == k[1] }.to_h # {"aa"=>"aa", "bb"=>"bb", ... compare( toro2k: -> { hash.to_set >= find.to_set }, MarekLipka: -> { hash.merge(find) == hash }, CarySwoveland: -> { (find.to_a - hash.to_a).empty? }, ArupRakshit: -> { arr = hash.to_a; find.all? { |pair| arr.include?(pair) } } )

Resultado:

Running each test 2 times. Test will take about 1 second. MarekLipka is faster than toro2k by 3x ± 0.1 toro2k is faster than CarySwoveland by 39.99999999999999% ± 10.0% CarySwoveland is faster than ArupRakshit by 1.9x ± 0.1


Desde Ruby 2.3, también puede hacer lo siguiente para verificar si se trata de un subconjunto

hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7} {} <= hash # true {f: 6, c: 3} <= hash # true {f: 6, c: 1} <= hash # false


La diferencia de matriz parece más fácil:

class Hash def include_hash?(h) (h.to_a - to_a).empty? end end h = {a: 1, b: 2} h.include_hash?({b: 2}) #=> true h.include_hash?({b: 3}) #=> false


La solución que se me ocurrió utilizar Hash#merge método de Hash#merge :

class Hash def include_hash?(hash) merge(hash) == self end end hash = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7} hash.include_hash?({}) # => true hash.include_hash?(f: 6, c:3) # => true hash.include_hash?(f: 6, c:1) # => false


Tu puedes hacer :

def include_hash?(hash,subset_hash) arr = hash.to_a subset_hash.all? { |pair| arr.include?(pair) } end