Reputation: 195
I'm trying to initialize an instance of a class from within a loop and am not sure how I would name the object so that it has a new name with each iteration so I don't have five objects/instances all called 'my_animal'?
my_array = ["Fluffy", "Lala", "Jo", "Cersei", "Berlin"]
my_array.each do |e|
my_animal = Animal.new(e)
end
class Animal
attr_accessor :name
def initialize (name)
@name = name
end
end
Upvotes: 1
Views: 1742
Reputation: 110665
You could do this:
my_array = ["Fluffy", "Lala", "Jo", "Cersei", "Berlin", "Jo"]
arr = my_array.each_with_index.with_object([]) do |(e,i),a|
a << Animal.send(:new, "#{e}#{i}")
end
#=> [#<Animal:0x007fe3e4087b20 @name="Fluffy0">,
# #<Animal:0x007fe3e4087a80 @name="Lala1">,
# #<Animal:0x007fe3e40879e0 @name="Jo2">,
# #<Animal:0x007fe3e4087940 @name="Cersei3">,
# #<Animal:0x007fe3e4087878 @name="Berlin4">,
# #<Animal:0x007fe3e31d5618 @name="Jo5">]
arr.map(&:name)
#=> ["Fluffy0", "Lala1", "Jo2", "Cersei3", "Berlin4", "Jo5"]
Alternatively, the following way conveys additional information:
my_array = ["Fluffy", "Lala", "Jo", "Cersei", "Lala", "Jo", "Berlin", "Jo"]
arr = my_array.each_with_object([]) do |s,a|
instance = a.reverse.find { |i| i.name =~ /^#{s}/ }
if instance
old_name = instance.name
prefix, nbr = old_name.split(/(\d+)/)
new_name = "#{prefix}#{((nbr.to_i)+1).to_s}"
else
new_name = "#{s}0"
end
a << Animal.send(:new, new_name)
end
#=> [#<Animal:0x007fe3e402e458 @name="Fluffy0">,
# #<Animal:0x007fe3e402e1b0 @name="Lala0">,
# #<Animal:0x007fe3e402dc38 @name="Jo0">,
# #<Animal:0x007fe3e402d120 @name="Cersei0">,
# #<Animal:0x007fe3e402c540 @name="Lala1">,
# #<Animal:0x007fe3e4097d68 @name="Jo1">,
# #<Animal:0x007fe3e4096d00 @name="Berlin0">,
# #<Animal:0x007fe3e4096698 @name="Jo2">]
arr.map(&:name)
#=> ["Fluffy0", "Lala0", "Jo0", "Cersei0", "Lala1", "Jo1", "Berlin0", "Jo2"]
Upvotes: 2
Reputation: 631
What happend on your code, its that every instance you create on my_animal = Animal.new(e)
its lost. You have to keep trace of all of them on some structure. Like a dictionary (hash) or array.
This could be helpful:
class Animal
attr_accessor :name
def initialize (name)
@name = name
end
end
my_array = ["Fluffy", "Lala", "Jo", "Cersei", "Berlin"]
my_instances = {}
my_array.each do |e|
my_animal = Animal.new(e)
my_instances[e] = my_animal
end
Now you have a name (string) of your array with an object. It will be something like:
my_instance = { "Fluffy" => #<Animal:0x0000000280d638 @name="Fluffy">,
"Lala" => #<Animal:0x0000000280d5e8 @name="Lala">,
"Jo" => #<Animal:0x0000000280d598 @name="Jo">,
"Cersei" => #<Animal:0x0000000280d548 @name="Cersei">,
"Berlin" => #<Animal:0x0000000280d4f8 @name="Berlin">
}
Upvotes: 1
Reputation: 717
You can try to put them in a Hash, then you can access them like my_animals["Lala"]
.
class Animal
attr_accessor :name
def initialize (name)
@name = name
end
end
my_array = ["Fluffy", "Lala", "Jo", "Cersei", "Berlin"]
my_animals = Hash.new
my_array.each do |e|
my_animals[e] = Animal.new(e)
end
Upvotes: 1
Reputation: 11
Push all new objects into an array rather than a static variable and then you can access them numerically.
Upvotes: 1