template sintax escape code ruby hash

sintax - Aplanar hash en una cuerda en Ruby



haml sintax (6)

¿Qué hay de conseguirlo en formato JSON? De esa forma el formato es claro.

Hay muchas herramientas JSON para ruby. Nunca los probé, sin embargo. Pero la salida se deslizará a javascript, etc., más fácilmente. Probablemente una línea.

El gran ahorro, sin embargo, estaría en la documentación, ya que necesitará mucho menos.

¿Hay alguna forma de aplanar un hash en una cadena, con delimitadores opcionales entre claves y valores, y pares clave / valor?

Por ejemplo, print {:a => :b, :c => :d}.flatten(''='',''&'') debería imprimir a=b&c=d

Escribí un código para hacer esto, pero me preguntaba si había una manera más ordenada:

class Hash def flatten(keyvaldelimiter, entrydelimiter) string = "" self.each do |key, value| key = "#{entrydelimiter}#{key}" if string != "" #nasty hack string += "#{key}#{keyvaldelimiter}#{value}" end return string end end print {:a => :b, :c => :d}.flatten(''='',''&'') #=> ''c=d&a=b''

Gracias


Bueno, podrías hacerlo con métodos y matrices estándar:

class Hash def flatten(keyvaldelimiter, entrydelimiter) self.map { |k, v| "#{k}#{keyvaldelimiter}#{v}" }.join(entrydelimiter) end end

También podría estar interesado en el método Rails to_query .

Además, obviamente, puede escribir "#{k}#{keyvaldelimiter}#{v}" como k.to_s + keyvaldelimiter + v.to_s ...


Ligera variación de la versión de @ elektronaut:

En realidad puedes poner solo un |e| allí en lugar de |k, v| en cuyo caso e es una matriz de dos elementos y puede llamar a e.join(''='') . En total, tienes algo así como

class Hash def join(keyvaldelim=$,, entrydelim=$,) # $, is the global default delimiter map {|e| e.join(keyvaldelim) }.join(entrydelim) end end {a: 100, b: 200}.join(''='', ''&'') # I love showing off the new Ruby 1.9 Hash syntax # => ''a=100&b=200''


No anularía .flatten , que ya está definido:

Devuelve una nueva matriz que es un aplanamiento unidimensional de este hash. Es decir, para cada clave o valor que es una matriz, extraiga sus elementos en la nueva matriz. A diferencia de Array # flatten, este método no se aplana recursivamente de forma predeterminada. Si el argumento de nivel opcional determina el nivel de recursión para aplanar.

Esta es la forma más sencilla de hacerlo de la que soy consciente:

{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join(''&'') # => "a=100&b=200"


No estoy seguro de si hay una forma integrada, pero aquí hay un código más corto:

class Hash def flatten(kvdelim='''', entrydelim='''') self.inject([]) { |a, b| a << b.join(kvdelim) }.join(entrydelim) end end puts ({ :a => :b, :c => :d }).flatten(''='', ''&'') # => a=b&c=d


Si está intentando generar una cadena de consulta url, seguramente debería usar un método como activesupport''s to_param (aliased to_query). Imagine los problemas si tiene un signo de & signo igual en los datos en sí.

to_query se encarga de escapar:

>> require ''active_support/core_ext/object'' >> {''a&'' => ''b'', ''c'' => ''d''}.to_query >> => "a%26=b&c=d"

EDITAR

@fahadsadah hace un buen punto acerca de no querer cargar Rails. Incluso active_support / core_ext / object cargará 71 archivos. También monos parches de las clases principales.

Una solución ligera y limpia:

require ''rack'' # only loads 3 files {''a&'' => ''b'', ''c'' => ''d''}.map{|pair| pair.map{|e| Rack::Utils.escape(e.to_s) }.join(''='') }.join(''&'') # => "a%26=b&c=d"

Es importante escapar, de lo contrario, la operación no es reversible.