[英]Ruby: replacing elements in array based on their value
我直接檢查了這個問題和其他類似的問題 ,但都沒有提供使用多個測試值替換數組元素的解決方案。
我有一個Ruby數組:
array = ["america", "europe", "asia", "africa", "france", "usa", "spain", "paris", "los angeles"]
我想轉換此數組,以獲得以下結果:
array = ["continent", "continent", "continent", "continent", "country", "country", "country", "city", "city"]
我的第一個嘗試是做這樣的事情:
array.collect! do |element|
(element == "america") ? "continent" : element
(element == "europe") ? "continent" : element
(element == "asia") ? "continent" : element
(element == "africa") ? "continent" : element
(element == "france") ? "country" : element
(element == "usa") ? "country" : element
(element == "spain") ? "country" : element
(element == "paris") ? "city" : element
(element == "los angeles") ? "city" : element
end
這段代碼有兩個問題:
我不確定這是在do
end
使用Ruby block
的方法。
這段代碼不是DRY
,我相信我可以使用一組三個case
循環,一個用於大洲,一個用於國家,一個用於城市。
這是一個更好的方法
array.collect! do |element|
case element
when 'america', 'europe', 'asia', 'africa'
'continent'
when 'france', 'spain'
'country'
when 'paris', 'los angeles'
'city'
else
element
end
end
我會使用哈希進行查找。 它是O(1),非常簡單。 如果鍵不存在,則fetch的第二個參數是默認值。
INDEX = {
"america" => "continent",
"europe" => "continent",
"asia" => "continent",
"africa" => "continent",
"france" => "country",
"usa" => "country",
"spain" => "country",
"paris" => "city",
"los angeles" => "city"
}
[
"america",
"europe",
"asia",
"africa",
"france",
"usa",
"spain",
"paris",
"los angeles",
"not indexed"
].map{|key| INDEX.fetch(key, key) }
您不能獲得比這更多的DRY。 (還要注意,這與TJ Singleton的做法非常相似)
array = ["america", "europe", "asia", "africa", "france", "usa", "spain", "paris", "los angeles"]
definitions = {
"continent" => ["america", "europe", "asia", "africa"],
"country" => ["france", "usa", "spain"],
"city" => ["paris", "los angeles"],
"planet" => ["mars","earth"]
}
inverse_array = definitions.map {|k,v| v.map { |e| [e, k]}}.flatten(1)
inverse_hash = Hash[inverse_array]
output = array.map { |e| inverse_hash[e] }
puts output.inspect
通過使用Set
跟蹤大洲,國家和城市是什么來清理呢? 集合中的查找為O(1),因此在這里穿起來也不差:
continents = Set.new ["america", "europe", "asia", "africa"]
countries = Set.new ["france", "usa", "spain"]
cities = Set.new ["paris", "los angeles"]
array = ["america", "europe", "asia", "africa", "france", "usa", "spain", "paris", "los angeles"]
newArray = array.map{ |c|
puts c
if continents.include? c
'continent'
elsif countries.include? c
'country'
elsif cities.include? c
'city'
else
'unknown'
end
}
使用地圖的另一個解決方案,我們創建一個查找表,其中的鍵是大洲/國家/城市,值是相應的字符串“ continent”,“ country”或“ city”:
continents = ["america", "europe", "asia", "africa"].each_with_object({}) { |k,h| h[k] = 'continent' }
countries = ["france", "usa", "spain"].each_with_object({}) { |k,h| h[k] = 'country' }
cities = ["paris", "los angeles"].each_with_object({}) { |k,h| h[k] = 'city' }
array = ["america", "europe", "asia", "africa", "france", "usa", "spain", "paris", "los angeles"]
newArray = array.map{ |c| continents[c] || countries[c] || cities[c] || c }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.