按属性查找对象

Find object by attribute

我有一个 ruby class 这样的:

class Table
  def initialize(name)
    @name = name
    @columns = {}
  end
end

我正在创建不同的对象:

table_1 = Table.new("First")
table_2 = Table.new("Second")
table_3 = Table.new("Third")

如何在 Table class 的对象中找到具有 "Second" 作为 name 属性的对象?

让我们为 name 属性添加一个 getter 方法

class Table
  attr_reader :name

  def initialize(name)
    @name = name
    @columns = {}
  end
end

现在,如果您有一个包含 Table 个对象的数组

arr = [Table.new("First"), Table.new("Second"), Table.new("Third")]

您可以按名称查找

arr.find { |table| table.name == "Second" }
 => #<Table:0x007f862107eb18 @name="Second", @columns={}> 

不创建任何额外的数据结构:

ObjectSpace.each_object(Table).find { |object| object.instance_variable_get(:@name) == "Second" }
=> #<Table:0x007f9f912b0ce0 @columns={}, @name="Second">

您可以使用可枚举 find 或可枚举模块中的任何类似方法:

class Table
  attr_reader :name
  def initialize(name)
    @name = name
    @columns = {}
  end
end

table_1 = Table.new("First")
table_2 = Table.new("Second")
table_3 = Table.new("Third")

x = [table_1, table_2, table_3].find { |t| t.name == "Second" }

puts x.name => "Second"

假设我们在 Tablename 上有 reader:

class Table
  attr_reader :name

  def initialize(name)
    @name = name
    @columns = {}
  end
end

我鼓励您将这些 Table classes 的对象存储在 list/array:

table_1 = Table.new("First")
table_2 = Table.new("Second")
table_3 = Table.new("Third")

tables = [table_1, table_2, table_3]

然后可以使用 find(如其中一个答案中所述)或 detect:

来查找它
tables.detect { |t| t.name == "Second" } #=> table_2 object

如果您想更进一步,我们可以让另一个 class 维护这个数组:

class TableList
  attr_reader :tables
  def initialize
    @tables = tables
  end

  def add(table)
    @tables << table
  end

  def find_by_name(name)
    tables.detect{ |table| table.name == name }
  end
end

然后可以用作:

table_1 = Table.new("First")
table_2 = Table.new("Second")
table_3 = Table.new("Third")
table_list = TableList.new
table_list.add(table_1)
table_list.add(table_2)
table_list.add(table_3)

table_list.find_by_name('Second') #=> table_2 object

您可以在 class 中保留对实例数组的引用。

class Table
  @instances = []
  class << self
    attr_accessor :instances
  end

  def initialize(name)
    @name = name
    @columns = {}
    self.class.instances << self
  end
end

然后你可以通过

获取所有的实例
Table.instances

然而,这将阻止所有 Table 对象被垃圾收集,因此只有当您只有少量 Table 并且该数量永远不会增长时才可行,否则您会有内存泄漏。