2016-07-30 51 views
0

我在数组objects中有一些对象。给定一个特定的属性值对,我需要一个函数返回匹配它的第一个对象。例如,给定objects.byName "John",它应返回第一个对象name: "John"从数组中检索满足某些特征的对象

目前我在做这个:

def self.byName name 
    ID_obj_by_name = {} 
    @@objects.each_with_index do |o, index| 
    ID_obj_by_name[o.name] = index 
    end 
    @@objects[ID_obj_by_name[name]] 
end 

但似乎很慢,并且使用了大量的内存。我该如何改进?

+0

除了(为此[可枚举# find](http://ruby-doc.org/core-2.3.0/Enumerable.html#method-i-find)就是答案,如@Ursus所示),有一些事情比较突出:1)'ID_ obj_by_name',因为它以大写字母开头,是一个常量。你不能使用赋值在一个方法内创建一个常量:'def a; A = 1;结束#=> SyntaxError:动态常量赋值。做那个(说)'id_obj_by_name'。 2)Ruby惯例是将* snake case *用于变量和方法的名称:'by_name'而不是'byName'。你不必遵循这个惯例,但我们99%的人都这么做。 (续)... –

+0

... 3)您的方法必须位于未指定的类中,因为无法从“顶级”访问类变量(@@对象)。因此,您应该将该方法包装在类定义中。 –

回答

0

尝试像

def self.by_name name 
    @@objects.find { |o| o.name == name } 
end 
1

如果您需要的性能,您应该考虑这种方法:

require 'benchmark' 

class Foo 
    def initialize(name) 
    @name = name 
    end 

    def name 
    @name 
    end 
end 

# Using array ###################################################################### 
test = [] 
500000.times do |i| 
    test << Foo.new("ABC" + i.to_s + "#[email protected]#@!DS") 
end 

puts "using array" 
time = Benchmark.measure { 
    result = test.find { |o| o.name == "ABC250000#[email protected]#@!DS" } 
} 
puts time 
#################################################################################### 
# Using a hash ##################################################################### 

test = {} 
i_am_your_object = Object.new 
500000.times do |i| 
    test["ABC" + i.to_s + "#[email protected]#@!DS"] = i_am_your_object 
end 

puts "using hash" 
time = Benchmark.measure { 
    result = test["ABC250000#[email protected]#@!DS"] 
} 
puts time 
#################################################################################### 

结果:

using array 
    0.060000 0.000000 0.060000 ( 0.060884) 
using hash 
    0.000000 0.000000 0.000000 ( 0.000005) 
从你的问题
相关问题