使用哈希问题中的关键字切换字符串中的单词
Switching words in string with keywords from hash problem
我正在尝试创建一种方法来将字符串中的单词与散列中的关键字进行切换。例如,有字符串:
my_string = "France france USA usa ENGLAND england ENGland"
这是我的哈希:
my_hash = {"england" => "https://google.com"}
还有一个循环:
occurrences = {}
my_string.gsub!(/\w+/) do |match|
key = my_hash[match.downcase]
count = occurrences.store(key, occurrences.fetch(key, 0).next)
count > 2 ? match : "<a href = #{key}>#{match}</a>"
end
这个循环的输出是:
<a href = >France</a> <a href = >france</a> USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland
预期输出:
France france USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland
你在这里看到的问题是我的循环总是接管字符串中前两个单词的 <a href>
标记,无论它们是否在哈希中(正如你在 [=30 中看到的那样) =] 示例)并且它应该像 'England' 示例中那样工作(前两个 'Englands' 成为超链接但不是第三个,因为它应该工作)。
P.S - 附加问题:有什么方法可以避免字符串中已经存在的超链接而不去碰它们?例如 - 如果字符串中已经有一个 'England' 超链接但带有另一个 href.
我不是 100% 清楚你的问题所需的输出是什么,但如果你只想替换与哈希中的键匹配的单词,只需添加一个 if (或 next
) 在你的哈希查找之后。此外,变量 key
用于存储查找到的 value
,因此我将其重命名并递增 key
而不是 occurrences
哈希中的 value
。这似乎更符合你的要求。
occurrences = {}
my_string.gsub!(/\w+/) do |match|
key = match.downcase
value = my_hash[key]
next match unless value
count = occurrences.store(key, occurrences.fetch(key, 0).next)
count > 2 ? match : "<a href = #{value}>#{match}</a>"
end
my_string = "France france USA usa ENGLAND england ENGland"
my_hash = {"england"=>"https://google.com"}
my_string.split
.chunk(&:downcase)
.flat_map do |country,a|
a.flat_map.with_index do |s,i|
if i < 2 && my_hash.key?(country)
"<a href = #{my_hash[country]}>#{s}</a>"
else
s
end
end
end.join(' ')
#=> "France france USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland"
见Enumerable#chunk and Enumerable#flat_map。
注意
enum0 = my_string.split.chunk(&:downcase)
#=> #<Enumerator: #<Enumerator::Generator:0x00007ff90c13bc28>:each>
这个枚举器生成的值可以通过将其转换为数组来查看。
enum0.to_a
#=> [["france", ["France", "france"]], ["usa", ["USA", "usa"]],
# ["england", ["ENGLAND", "england", "ENGland"]]]
然后
enum1 = enum0.flat_map
#=> #<Enumerator: #<Enumerator: #<Enumerator::Generator:0x00007ff90c113e58>:each>:flat_map>
enum1
生成并赋值给两个block变量的初始值如下
country, a = enum1.next
#=> ["france", ["France", "france"]]
country
#=> "france"
a #=> ["France", "france"]
我正在尝试创建一种方法来将字符串中的单词与散列中的关键字进行切换。例如,有字符串:
my_string = "France france USA usa ENGLAND england ENGland"
这是我的哈希:
my_hash = {"england" => "https://google.com"}
还有一个循环:
occurrences = {}
my_string.gsub!(/\w+/) do |match|
key = my_hash[match.downcase]
count = occurrences.store(key, occurrences.fetch(key, 0).next)
count > 2 ? match : "<a href = #{key}>#{match}</a>"
end
这个循环的输出是:
<a href = >France</a> <a href = >france</a> USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland
预期输出:
France france USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland
你在这里看到的问题是我的循环总是接管字符串中前两个单词的 <a href>
标记,无论它们是否在哈希中(正如你在 [=30 中看到的那样) =] 示例)并且它应该像 'England' 示例中那样工作(前两个 'Englands' 成为超链接但不是第三个,因为它应该工作)。
P.S - 附加问题:有什么方法可以避免字符串中已经存在的超链接而不去碰它们?例如 - 如果字符串中已经有一个 'England' 超链接但带有另一个 href.
我不是 100% 清楚你的问题所需的输出是什么,但如果你只想替换与哈希中的键匹配的单词,只需添加一个 if (或 next
) 在你的哈希查找之后。此外,变量 key
用于存储查找到的 value
,因此我将其重命名并递增 key
而不是 occurrences
哈希中的 value
。这似乎更符合你的要求。
occurrences = {}
my_string.gsub!(/\w+/) do |match|
key = match.downcase
value = my_hash[key]
next match unless value
count = occurrences.store(key, occurrences.fetch(key, 0).next)
count > 2 ? match : "<a href = #{value}>#{match}</a>"
end
my_string = "France france USA usa ENGLAND england ENGland"
my_hash = {"england"=>"https://google.com"}
my_string.split
.chunk(&:downcase)
.flat_map do |country,a|
a.flat_map.with_index do |s,i|
if i < 2 && my_hash.key?(country)
"<a href = #{my_hash[country]}>#{s}</a>"
else
s
end
end
end.join(' ')
#=> "France france USA usa <a href = https://google.com>ENGLAND</a> <a href = https://google.com>england</a> ENGland"
见Enumerable#chunk and Enumerable#flat_map。
注意
enum0 = my_string.split.chunk(&:downcase)
#=> #<Enumerator: #<Enumerator::Generator:0x00007ff90c13bc28>:each>
这个枚举器生成的值可以通过将其转换为数组来查看。
enum0.to_a
#=> [["france", ["France", "france"]], ["usa", ["USA", "usa"]],
# ["england", ["ENGLAND", "england", "ENGland"]]]
然后
enum1 = enum0.flat_map
#=> #<Enumerator: #<Enumerator: #<Enumerator::Generator:0x00007ff90c113e58>:each>:flat_map>
enum1
生成并赋值给两个block变量的初始值如下
country, a = enum1.next
#=> ["france", ["France", "france"]]
country
#=> "france"
a #=> ["France", "france"]