遍历数组对象。然后访问对象方法,如果找到正确的方法。否则,在数组中创建一个新的对象
问题描述:
我从一个空数组和一个键值的哈希开始。遍历数组对象。然后访问对象方法,如果找到正确的方法。否则,在数组中创建一个新的对象
我想遍历哈希并将其与空数组进行比较。如果每个k,v对的值都不存在于数组中,我想创建一个具有该值的对象,然后访问一个对象方法以将该对象追加到数组中。
这是我的代码
class Test
def initialize(name)
@name = name
@values = []
end
attr_accessor :name
def values=(value)
@values << value
end
def add(value)
@values.push(value)
end
end
l = []
n = {'server_1': 'cluster_x', 'server_2': 'cluster_y', 'server_3': 'cluster_z', 'server_4': 'cluster_x', 'server_5': 'cluster_y'}
n.each do |key, value|
l.any? do |a|
if a.name == value
a.add(key)
else
t = Test.new(value)
t.add(key)
l << t
end
end
end
p l
我希望看到这一点:
[
#<Test:0x007ff8d10cd3a8 @name=:cluster_x, @values=["server_1, server_4"]>,
#<Test:0x007ff8d10cd2e0 @name=:cluster_y, @values=["server_2, server_5"]>,
#<Test:0x007ff8d10cd1f0 @name=:cluster_z, @values=["server_3"]>
]
相反,我只是得到一个空数组。
我认为条件if a.name == value
没有被满足,然后add方法没有被调用。
答
@Cyzanfar给我的线索,以寻找什么,而且我找到了答案在这里
https://*.com/a/34904864/5006720
n.each do |key, value|
found = l.detect {|e| e.name == value}
if found
found.add(key)
else
t = Test.new(value)
t.add(key)
l << t
end
end
答
@ARL你几乎没有!您需要考虑的最后一件事情是found
实际上会返回一个对象,因为detect
会在某个点找到匹配的对象。
n.each do |key, value|
found = l.detect {|e| e.name == value}
if found
found.add(key)
else
t = Test.new(value)
t.add(key)
l << t
end
end
实际上,你只需要添加的Test
时found
回报nil
一个新的实例。此代码应得到你想要的输出:
[
#<Test:0x007ff8d10cd3a8 @name=:cluster_x, @values=["server_1, server_4"]>,
#<Test:0x007ff8d10cd2e0 @name=:cluster_y, @values=["server_2, server_5"]>,
#<Test:0x007ff8d10cd1f0 @name=:cluster_z, @values=["server_3"]>
]
答
我观察你的代码两件事情:
def values=(value)
@values << value
def add(value)
@values.push(value)
- 两种方法做同样的事情,推着一辆价值,
<<
是一种句法糖含义推 - 您已更改
values=
的含义,该含义通常保留给setter方法,相当于attire_writer :values
。
只是为了说明,有很多方法可以做的事情在Ruby中,我提出以下建议:
class Test
def initialize(name, value)
@name = name
@values = [value]
end
def add(value)
@values << value
end
end
h_cluster = {} # intermediate hash whose key is the cluster name
n = {'server_1': 'cluster_x', 'server_2': 'cluster_y', 'server_3': 'cluster_z',
'server_4': 'cluster_x', 'server_5': 'cluster_y'}
n.each do | server, cluster |
puts "server=#{server}, cluster=#{cluster}"
cluster_found = h_cluster[cluster] # does the key exist ? => nil or Test
# instance with servers list
puts "cluster_found=#{cluster_found.inspect}"
if cluster_found
then # add server to existing cluster
cluster_found.add(server)
else # create a new cluster
h_cluster[cluster] = Test.new(cluster, server)
end
end
p h_cluster.collect { | cluster, servers | servers }
执行:
$ ruby -w t.rb
server=server_1, cluster=cluster_x
cluster_found=nil
server=server_2, cluster=cluster_y
cluster_found=nil
server=server_3, cluster=cluster_z
cluster_found=nil
server=server_4, cluster=cluster_x
cluster_found=#<Test:0x007fa7a619ae10 @name="cluster_x", @values=[:server_1]>
server=server_5, cluster=cluster_y
cluster_found=#<Test:0x007fa7a619ac58 @name="cluster_y", @values=[:server_2]>
[#<Test:0x007fa7a619ae10 @name="cluster_x", @values=[:server_1, :server_4]>,
#<Test:0x007fa7a619ac58 @name="cluster_y", @values=[:server_2, :server_5]>,
#<Test:0x007fa7a619aac8 @name="cluster_z", @values=[:server_3]>]
''l.any永远是假的因为你永远不会添加任何东西。 – Cyzanfar
可能还想看看'group_by',这里可能会帮助你,或者可能不会帮助你:'n.group_by {| _,v | v}'或'n.keys.group_by {| key | n [key]}' –