Ruby 再写一句;“更好”;代码

Ruby 再写一句;“更好”;代码,ruby,arrays,coding-style,initialization,Ruby,Arrays,Coding Style,Initialization,我正在使用Ruby1.9,我想知道是否有一种“更好”的方法来编写下面的代码 array_one = [] array_two = [] some_array.each { |value| array_one << value.id array_two << value.name } array_one=[] 数组_two=[] 一些_数组。每个{|值| array\u one这里的代码模式通常是一个想要退出的折叠(或者更一般地说是一种亚同

我正在使用Ruby1.9,我想知道是否有一种“更好”的方法来编写下面的代码

  array_one = []
  array_two = []
  some_array.each { |value|
    array_one << value.id
    array_two << value.name
  }
array_one=[]
数组_two=[]
一些_数组。每个{|值|

array\u one这里的代码模式通常是一个想要退出的
折叠(或者更一般地说是一种亚同态)的明确标志。Ruby确实提供了一种内置的折叠方法,出于历史原因,它被称为
注入

未经测试:

array_one, array_two = some_array.
  inject([[], []]) {|(array_one, array_two), value|
    [array_one << value.id, array_two << value.name]
}
请注意,这将遍历
某些数组两次。但是,除非您有可靠的基准测试和分析结果表明这种双重遍历是应用程序中性能问题的主要来源,否则您真的不应该担心这一点。

您可以使用以下方法:


正如Jörg W Mittag在其回答中提到的,此解决方案还将遍历源数组两次。

您可能需要使用
转置
将包含两个元素数组的n元素数组转换为两个n元素数组:

array_one, array_two = some_array.map {|value| [value.id, value.name]}.transpose

下面是一个例子,虽然它相当简洁。

我认为它已经足够好了。我们通常对具有多条指令的块使用do结束形式,但是,除此之外,显式比隐式好。就像你提出的那样,它将遍历“some_数组”两次……我认为这对性能不好。我很好奇你为什么认为迭代twice很慢。我打赌它比这些答案中的一些答案(比如inject)快得多在理论上,你应该计算操作的数量,而不是迭代的数量。迭代一次并在每次迭代中做两件事与迭代两次并在每次迭代中只做其中一件事是一样的,除了收集的微小开销,即far比分配一堆需要垃圾收集的数组要小。另外,这个答案非常清楚。运行
timeruby-e'10000000.times{i|i.to_.s}
timeruby-e'5000000.times{i|i.to_.s};5000000.times{i|i.to_.s}“
几次,然后比较结果。顺便说一句:在哪里我可以找到一些信息来理解“fold”(而不是)?为什么要使用
inject
而不是
each_with_object
?虽然大多数关于Ruby的书都谈到了块,但我认为很多Ruby的书都没有明确提到函数编程(在更高级别的函数或不可变对象意义下)详细说明。@user502052:虽然我希望下面问题的答案更好,但请仔细阅读tokland的答案到的链接
array_one = some_array.collect { |value| value.id }
array_two = some_array.collect { |value| value.name }
array_one, array_two = some_array.map {|value| [value.id, value.name]}.transpose