2016-07-30 48 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) 
從你的問題
相關問題