I have been searching for a method to concatenate several arrays.
A had an Array like this
arr1 = [ [1,2,3], [4,5,6], [7,[8,9]] ]
and wanted to produce
arr2 = [1, 2, 3, 4, 5, 6, 7, [8, 9]]
Looking at the methods of the Array class I found some methods that
do similar things, but none that fits exactly:
+ concatenate TWO Arrays
concat concatenate TWO arrays destructively modifying
the first
flatten RECURSIVELY flattens elements into a new Array
The best way I have found until now, of doing what I want is
arr2 = arr1.inject([]) {|acc,x| acc.concat x}
But I feel that the thing I want to do (concatenating a variable
number arrays) is such a natural thing, that it deserves a cleaner
way of being expressed.
Have I missed some other method that does this in a readable way ?
“Johan Holmberg” holmberg@iar.se schrieb im Newsbeitrag
news:Pine.GSO.4.50.0401141612480.29527-100000@pjakkur.iar.se…
Hi!
I have been searching for a method to concatenate several arrays.
A had an Array like this
arr1 = [ [1,2,3], [4,5,6], [7,[8,9]] ]
and wanted to produce
arr2 = [1, 2, 3, 4, 5, 6, 7, [8, 9]]
Looking at the methods of the Array class I found some methods that
do similar things, but none that fits exactly:
+ concatenate TWO Arrays
concat concatenate TWO arrays destructively modifying
the first
flatten RECURSIVELY flattens elements into a new Array
The best way I have found until now, of doing what I want is
arr2 = arr1.inject([]) {|acc,x| acc.concat x}
That’s exactly what I’d do.
But I feel that the thing I want to do (concatenating a variable
number arrays) is such a natural thing, that it deserves a cleaner
way of being expressed.
All other ways that I can think of are more verbose and not necessarily
cleander - let alone faster. The version using each would look like
arr2=
arr1.each {|x| arr2.concat x}
Not really an improvement IMHO.
Have I missed some other method that does this in a readable way ?
I have been searching for a method to concatenate several arrays.
A had an Array like this
arr1 = [ [1,2,3], [4,5,6], [7,[8,9]] ]
and wanted to produce
arr2 = [1, 2, 3, 4, 5, 6, 7, [8, 9]]
[snip]
But I feel that the thing I want to do (concatenating a variable
number arrays) is such a natural thing, that it deserves a cleaner
way of being expressed.
The best way I have found until now, of doing what I want is
arr2 = arr1.inject([]) {|acc,x| acc.concat x}
You can also use “+” here:
arr2 = arr1.inject() { |a,x| a + x }
But I feel that the thing I want to do (concatenating a variable
number arrays) is such a natural thing, that it deserves a cleaner
way of being expressed.
If you extend Symbol like this:
class Symbol
def to_proc
lambda { |a, b| a.send(self, b) }
end
end
You could also write
arr2 = arr1.inject(, &:+)
That’s pretty similar to how it is done in most functional programming
languages.
···
On Wed, 2004-01-14 at 16:33, Johan Holmberg wrote:
On Wed, 2004-01-14 at 16:33, Johan Holmberg wrote:
The best way I have found until now, of doing what I want is
arr2 = arr1.inject([]) {|acc,x| acc.concat x}
You can also use “+” here:
arr2 = arr1.inject() { |a,x| a + x }
But I feel that the thing I want to do (concatenating a variable
number arrays) is such a natural thing, that it deserves a cleaner
way of being expressed.
If you extend Symbol like this:
class Symbol
def to_proc
lambda { |a, b| a.send(self, b) }
end
end
You could also write
arr2 = arr1.inject(, &:+)
That’s pretty similar to how it is done in most functional programming
languages.
Amazing! Only that it’s less efficient since your approach creates more
temporary arrays.
Amazing! Only that it’s less efficient since your approach creates
more temporary arrays.
That’s true: But it seems very clean to me.
I agree.
Where can I read about ‘to_proc’ and how it works ?
This trick uses the function block_pass in eval.c. If you pass an object
with & operator to a method, a conversion to a Proc object is attempted
in this function, by calling to_proc on this object. Usually there are
only Method and Proc objects in Ruby that implement this method. But you
can also define your own classes with to_proc if you like. Actually it’s
an application of duck typing.
···
On 2004-01-16 00:03:39 +0900, Johan Holmberg wrote:
I agree.
Where can I read about ‘to_proc’ and how it works ?
This trick uses the function block_pass in eval.c. If you pass an object
with & operator to a method, a conversion to a Proc object is attempted
in this function, by calling to_proc on this object. Usually there are
only Method and Proc objects in Ruby that implement this method. But you
can also define your own classes with to_proc if you like. Actually it’s
an application of duck typing.
Thanks for the explanation.
Is this documented somewhere or have you found out by reading the
code ?
One thing I wonder is if the ‘Symbol.to_proc’ method you described
is too global. What if we would like to define the method in a
different way somewhere else ?
Or is it poosible to define ‘Symbol.to_proc’ in a natural way ?
And in that case, why isn’t it already built into Ruby ?
/Johan Holmberg
···
On Fri, 16 Jan 2004, Florian Frank wrote:
On 2004-01-16 00:03:39 +0900, Johan Holmberg wrote: