请帮我创建名为hash_string的方法,以便它接受哈希并从其键/值对中创建一个字符串。 例如:
hash_string({id: 8, name: 'marry'}) # should return "id = 8, name = marry"
我之前尝试过相同的方式,它们是:
def hash_string(hash)
hash.to_s
end
和
def hash_string(hash)
set_value = hash.each {|key, value| puts "#{key} = #{value}" }
# set_value.join(",")
end
但他们没有用。请你解释一下,我该怎么做?
答案 0 :(得分:3)
def hash_string(hash); hash.map{|e| e.join(" = ")}.join(", ") end
当map
应用于哈希时,会应用to_a
,这会提供键值对。每个对都由e
适用的单个块变量join
捕获。
答案 1 :(得分:1)
将each
替换为map
,返回值而不是输出,然后您就完成了。
def hash_string(hash)
set_value = hash.map {|key, value| "#{key} = #{value}" }
set_value.join(",")
end
答案 2 :(得分:1)
还有其他方法吗? (你确实问过。)我认为这应该有效。反例,有人吗?
h = {:id=>8, name: "marry", "age"=>25, 7=>4}
#=> {:id=>8, :name=>"marry", "age"=>25, 7=>4}
h.to_s[1..-2].gsub(/:?([^:]+?)=>/,'\1 = ').gsub('"', '')
#=> "id = 8, name = marry, age = 25, 7 = 4"
h.to_s[1..-2]
将哈希值转换为字符串,并删除第一个({
)和最后一个(}
)个字符。:?
消耗:
如果紧接在随后的捕获组之前存在([^:]+?)
。:
是捕获组#1,它捕获除?
以外的一个或多个字符,非贪婪地(由=>
表示),然后是/:?([^:=>]+)=>/
。或者,可以'\1 = '
。" = "
,这是捕获组的内容,后跟"\\1 = "
。这可以用双引号(h = {:id=>8, "name"=>"mary"} #=> {:id=>8, "name"=>"mary"}
str0 = h.to_s #=> "{:id=>8, \"name\"=>\"mary\"}"
str1 = str0[1..-2] #=> ":id=>8, \"name\"=>\"mary\""
str2 = str1.gsub(/:?([^:]+?)=>/,'\1 = ') #=> "id = 8, \"name\" = \"mary\""
str2.gsub('"', '') #=> "id = 8, name = mary"
)编写。 让我们来看一个例子:
gsub
现在让我们仔细看看倒数第二个声明。
":id=>8, \"name\"=>\"mary\""
正在寻找以下字符串:
/:?([^:]+?)=>/
匹配正则表达式:
\1 =
每当找到一个时,它就会用\1
替换它,其中:?
表示正则表达式的唯一捕获组的内容。
在?
中,:
表示“匹配id
(如果存在)。它会在([^:]+?)
之前找到一个。现在转到”捕获组“(捕获组#1),由括号指定:[^:]+?
。:
捕获除=>
以外的一个或多个字符。
当捕获组后跟=>
时,它将捕获匹配的字符,直到达到id=>8
。但是哪一对,\"name\"=>\"mary\"
中的那个或([^:]+)
中的那个?正则表达式自然是“贪婪的”,所以如果捕获组是id=>8, \"name\"
,它将匹配 last ,捕获?
。为了防止这种情况发生,我们添加[^:]+?
以使=>
“非贪婪”匹配,这是由首先停止 id
遭遇,导致它只匹配gsub
。
:id=>
已匹配id
,其中\1
是捕获组的内容,可以通过:id=>
在字符串中引用。因此,它会将\1 =
替换为id =
=> :
。
等一下。捕获组与:?
不匹配,那么为什么我们在正则表达式的开头需要str2 = str1.gsub(/([^:]+?)=>/,'\1 = ') #=> ":id = 8, \"name\" = \"mary\""
?让我们试试没有:
:
如您所见,第一个gsub
未被删除。那是因为它不是\1 =
替换为:?
的匹配项的一部分。因此需要"
。
最后一个语句只是将每个{{1}}转换为空字符串(即删除双引号)。