簡體   English   中英

Ruby:根據值替換數組中的元素

[英]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

這段代碼有兩個問題:

  1. 我不確定這是在do end使用Ruby block的方法。

  2. 這段代碼不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM