Ruby:根据数值替换数组中的元素

时间:2015-11-19 19:18:16

标签: arrays ruby

我DID结帐this questionthat other similar question,它们都没有提供用多个测试值替换数组元素的解决方案。

我有一个Ruby数组:

httpd.conf, httpd-ssl.conf, and on the Services and Port Settings Menu

我想转换这个数组,得到以下结果:

array = ["america", "europe", "asia", "africa", "france", "usa", "spain", "paris", "los angeles"]

我的第一次尝试就是做那样的事情:

array = ["continent", "continent", "continent", "continent", "country", "country", "country", "city", "city"]

我对此代码有两个问题:

  1. 我不确定这是使用带有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 block的Ruby do的方法。

  2. 此代码不是end,我相信我可以使用一组三个DRY循环,一个用于大陆,一个用于国家,一个用于城市。

    < / LI>

4 个答案:

答案 0 :(得分:8)

这是一种更好的方法

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

答案 1 :(得分:4)

我使用哈希来进行查找。它是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) }

答案 2 :(得分:2)

你不能再得到比这更干的了。 (另请注意,这与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

答案 3 :(得分:0)

使用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
}

使用地图的另一个解决方案,我们创建一个查找表,其中键是大陆/国家/城市,值是相应的字符串“洲”,“国家”或“城市”:

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 }