我有一个带有XY坐标的对象(节点(数组。无论我在哪里找到覆盖另一个节点的节点(具有完全相同的 XY 坐标(,我都想将 Y 属性"up"编辑 3。
id,x,y都是我正在查看的对象的属性。并集体保存在节点数组中。
我希望遍历数组,每当存在重复的 XY 时,通过在 Y 属性中添加 3 来编辑第一个非唯一实例。如果找到另一个重复项,我希望将此对象的 Y 属性更改为 6,依此类推。
例如
NODE X Y
node1 267555 666777
node2 267555 666777
node3 245698 656400
node4 267555 666777
我希望节点 2 和节点 4 变成:
NODE X Y
node1 267555 666777
node2 267555 666780
node3 245698 656400
node4 267555 666783
本质上,对于重复 XY 的每个实例,将 3 添加到"Y",并且对于数组中存在覆盖节点的每个实例(实际数组要大得多(。
我已经设法使用识别重复项,但不确定如何进行:
duplicates = nodes.group_by{|i| [i.x, i.y] }.select{|k,v| v.length > 1}.values
但是我不想要一个新数组,我希望修改原始的"节点"数组属性。
谢谢
让我们从创建一个节点类开始。
class Nodes
attr_accessor :name, :x, :y
def initialize(name, x, y)
@name = name
@x = x
@y = y
end
end
接下来,创建问题中显示的实例。
nodes = [
Nodes.new("node1", 267555, 666777),
Nodes.new("node2", 267555, 666777),
Nodes.new("node3", 245698, 656400),
Nodes.new("node4", 267555, 666777)
]
#=> [#<Nodes:0x00005c7949ee8e40 @name="node1", @x=267555, @y=666777>,
# #<Nodes:0x00005c7949f57c50 @name="node2", @x=267555, @y=666777>,
# #<Nodes:0x00005c7949f57958 @name="node3", @x=245698, @y=656400>,
# #<Nodes:0x00005c7949f577a0 @name="node4", @x=267555, @y=666777>]
现在根据需要修改y
值。为此,我们使用方法Hash::new的形式,该方法采用称为默认值的参数。如果以这种方式创建了哈希h
,则h[k]
如果没有键k
,它将返回默认值。这有时称为计数哈希。
nodes.each_with_object(Hash.new(0)) do |inst,h|
y = inst.y
inst.y += 3 * h[y] if h.key?(y)
h[y] += 1
end
#=> {666777=>3, 656400=>1}
让我们看看nodes
现在的样子。
nodes
#=> [#<Nodes:0x00005c7949ee8e40 @name="node1", @x=267555, @y=666777>,
# #<Nodes:0x00005c7949f57c50 @name="node2", @x=267555, @y=666780>,
# #<Nodes:0x00005c7949f57958 @name="node3", @x=245698, @y=656400>,
# #<Nodes:0x00005c7949f577a0 @name="node4", @x=267555, @y=666783>]
nodes.map { |inst| [inst.name, inst.x, inst.y] }
#=> [["node1", 267555, 666777],
# ["node2", 267555, 666780],
# ["node3", 245698, 656400],
# ["node4", 267555, 666783]]