2010-06-15 17 views
40

有沒有一種方法可以將哈希平化爲字符串,在鍵和值之間使用可選的分隔符以及鍵/值對?將哈希平鋪到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' 

感謝

回答

92

我不會重寫.flatten ,這是已經被定義:

返回一個新數組,它是此的 一維展平散列。也就是說,對於作爲數組的每個鍵或值 ,將其元素 提取到新數組中。與 數組#平展不同,默認情況下,此方法不會 遞歸平展。如果 可選級別參數確定要遞減的 遞歸級別。

這是爲了做到這一點,我所知道的最簡單的方法:

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

您可以進一步簡化此操作。詳情請參閱我的回答。要點是用'| e |'代替'| k,v |',這使'e'成爲一個可以調用'e.join('=')'的數組。 – 2010-06-15 18:33:06

+1

如何做相反得到散列 – jenuine 2016-02-19 06:12:58

4

嗯,你可以用標準方法和陣列做:

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

您可能也有興趣Rails to_query method

而且,很明顯,你可以寫"#{k}#{keyvaldelimiter}#{v}"作爲k.to_s + keyvaldelimiter + v.to_s ...

+2

或'[k,v] .join(keyvaldelimiter)'。 – henrikhodne 2010-06-15 16:32:01

1

不知道是否有一個內置的方式,但這裏的一些短代碼:

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 
21

的@ 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' 
+5

我會嚴重質疑它是如何聰明是猴子補丁'哈希',特別是與一個非命名空間的方法名稱,如'加入'。雖然我期望得到這個,但我很驚訝地看到一位非常有經驗的開發人員的這種建議。 – akostadinov 2016-03-25 14:32:00

0

怎麼樣得到它在JSON格式。這樣的格式很清楚。

有很多用於ruby的JSON工具。雖然從未嘗試過。但是輸出當然會更容易滑入javascript等。可能只有一行。

儘管會在文檔中節省大筆費用,因爲您將需要更少的費用。

4

如果你想產生一個url查詢字符串,你肯定應該使用像activesupport的to_param(別名to_query)這樣的方法。想象一下,如果數據本身中有&符號或等號,則會出現問題。

to_query照顧逃逸的:

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

編輯

@fahadsadah使有關不希望加載Rails的好點。即使active_support/core_ext/object也會加載71個文件。它也猴子補丁核心類。

的輕量且簡潔的解決方案:

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" 

它逃跑是很重要的,否則操作是不可逆的。

+0

這一切都很好,這是一個很好的觀點,但我寧願不要求在創建源代碼散列時安裝Rails – 2012-03-24 17:36:46

+0

Rails for win! – 2016-07-13 20:18:05