How to check if an element exists and append string

Viewed 90

I have few items in my_list:

@my_list = {
  "all": [
    "prd02",
    "stg01",
    "prd01",
    "stg02"
    ],
  "prd": [
    "prd02",
    "prd01"
    ],      
  "stg": [
    "stg02",
    "stg01"
    ] 
}

Currently, I print all of them in all:

if @my_list['all'].include?(@item)
puts "#{@item}"

My current output is:

 prd02
 stg01
 prd01
 stg02

How can I check if that item is present in "prd" before printing the items? It should append "(prod)" and if that item is in "stg" it should append "(staging)".

I want to get my desired output as:

prd02 (prod)
stg01 (staging)
prd01 (prod)
stg02 (staging)

How can I check if the item is present in prd or stg?

if @my_list['all'].exists ? @my_list['prod'](@item)
puts "#{@item}.(prod)"
3 Answers

This should work:

my_list = {
  "all": [
    "prd02",
    "stg01",
    "prd01",
    "stg02"
    ],
  "prd": [
    "prd02",
    "prd01"
    ],
  "stg": [
    "stg02",
    "stg01"
    ]
}

my_list[:all].each do |item|
  if my_list[:prd].include?(item)
    puts "#{item} (prod)"
  elsif my_list[:stg].include?(item)
    puts "#{item} (staging)"
  end
end

Please also note:

  1. You have a syntax error in my_list declaration (missing ,)

  2. You need to use :all, :prd and :stg as symbols

See "What's the difference between a string and a symbol in Ruby?".

labels = { :prd=>"prod", :stg=>"staging" }

@my_list.each { |k,v| (@my_list[:all] & v).each { |item|
  puts "#{item} (#{labels[k]})" } unless k == :all }
  # prd02 (prod)
  # prd01 (prod)
  # stg01 (staging)
  # stg02 (staging)

As

@my_list[:all]
  #=> ["prd02", "stg01", "prd01", "stg02"] 

when

k = :prd
v = ["prd02", "prd01"]

we compute

@my_list[:all] & v
  #=> ["prd02", "stg01", "prd01", "stg02"] & ["prd02", "prd01"]
  #=> ["prd02", "prd01"]

See Array#&.

Congrats on learning Ruby. Since you are learning, I suggest an approach that illustrates how elegantly readable Ruby can be. This is neither the shortest nor the most verbose.

@my_list = {
  "all": [
    "prd02",
    "stg01",
    "prd01",
    "stg02"
    ],
  "prod": [
    "prd02",
    "prd01"
    ],      
  "staging": [
    "stg02",
    "stg01"
    ] 
}

collections = [:prod, :staging]

@my_list[:all].each do |item|
  output = item

  collections.each do |collection|
    output << " (#{collection.to_s})" if @my_list[collection].include?(item)
  end

  puts output
end

I would favor a naming convention that is a little more meaningful in your data structure by using "prod" and "staging" to match the variable names in collections and the outputted text.

This also allows you to quickly add additional collections by adding the corresponding symbol to the collections array.

Related