Выравнивание хеша в строку в Ruby

Существует ли способ сгладить хеш в строку с дополнительными разделителями между ключами и значениями и парами ключ/значение?

Например, print {:a => :b, :c => :d}.flatten('=','&') должен распечатать a=b&c=d

Я написал некоторый код, чтобы сделать это, но я задавался вопросом, был ли более опрятный путь:

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'

Спасибо

49
задан Fahad Sadah 15 June 2010 в 05:17
поделиться

5 ответов

Я бы не стал переопределять .flatten , который уже определен:

Возвращает новый массив, который является одномерное уплощение этого хэш. То есть для каждого ключа или значения это массив, извлеките его элементы в новый массив. В отличие от Массив # сгладить, этот метод не по умолчанию сглаживает рекурсивно. Если необязательный аргумент уровня определяет уровень рекурсии до сглаживания.

Это самый простой способ сделать это, о котором я знаю:

{:a => 100, :b => 200}.map{|k,v| "#{k}=#{v}"}.join('&')
# => "a=100&b=200"
107
ответ дан 7 November 2019 в 11:23
поделиться

Небольшая вариация версии @elektronaut:

На самом деле вы можете поставить там просто |e| вместо |k, v|, и тогда e будет массивом из двух элементов, и вы можете вызвать e.join('='). В целом получается что-то вроде

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'
22
ответ дан 7 November 2019 в 11:23
поделиться

Не уверен, есть ли встроенный способ, но вот более короткий код:

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
1
ответ дан 7 November 2019 в 11:23
поделиться

А как насчет того, чтобы получить его в формате JSON. Таким образом, формат ясен.

Для Ruby существует множество инструментов JSON. Однако никогда не пробовал их. Но тогда вывод, конечно, будет легче переходить в javascript и т. Д. Скорее всего одна строчка.

Однако большая экономия будет заключаться в документации, поскольку вам потребуется гораздо меньше.

0
ответ дан 7 November 2019 в 11:23
поделиться

Ну, вы можете сделать это с помощью стандартных методов и массивов:

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

Вас также может заинтересовать Rails to_query метод.

Также, очевидно, вы можете записать "#{k}#{keyvaldelimiter}#{v}" как k.to_s + keyvaldelimiter + v.to_s...

5
ответ дан 7 November 2019 в 11:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: