3

如果我在 ruby​​ 中有一个对象数组,我如何遍历数组并更新对象?

示例: test_arr具有以下值:(由 find_by_sql 获取)

test_arr = [
  {"id"=>1024, "value"=>"9999"},
  {"id"=>1025, "value"=>"9999"} 
]
test_arr.map{|r| r.value="1111"}

返回 ["1111", "1111"]

我需要类似的东西:(更新后)

[{"id"=>1024, "value"=>"1111"}>,
{"id"=>1025, "value"=>"1111"}>]

任何帮助将不胜感激。

4

4 回答 4

9

您必须使用each, 因为map它返回一个更改的数组。each正在迭代数组。

test_arr.each{|r| r.value="1111"}

test_arr.map{|r| r.value="1111"}

您返回一个更改后的数组,内容是块的结果(在示例中为“1111”)。随着map!数组被修改。

您还可以使用:

test_arr.map{|r| 
  r.value="1111"   # modify r
  r                # return r - you are replacing r with r
}

但正如已经提到的:each会更好。

于 2012-09-15T18:38:43.440 回答
3

如果您想立即保存它,请尝试以下操作:

test_arr.map{ |r| r.update_attributes( { :value => "1111" } ) }

如果您需要比这更高的性能,您可以尝试 update_all,并将对象数组中的 ID 传递给它。http://apidock.com/rails/ActiveRecord/Relation/update_all

于 2012-09-15T18:43:16.270 回答
2

实际上,您的代码应该成功更新属性。但我认为你混淆了mapeach方法。

map方法遍历整个数组并从每次迭代中收集结果,这就是为什么它的第二个别名是collect.

您需要的是each方法,这个方法只会遍历数组并执行块中描述的操作。

因此,您的代码应如下所示:

test_arr.each { |r| r.value="1111" }
test_arr.inspect 
#=> [#<SimpleClass:0xb74c8968 @attributes={"id"=>1024, "value"=>"1111"}>, #<SimpleClass:0xb74c8940 @attributes={"id"=>1025, "value"=>"1111"}>]
于 2012-09-15T18:53:41.210 回答
1

map 遍历数组并为您提供一个包含块结果的新数组。

test_arr = test_arr.map { |val|
   val.attr - new_value
   val # last line of the block is the return value
}

用于map!就地更新数组。

于 2012-09-15T18:38:01.007 回答