Forum: Ruby Newbie - several array questions

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cea563880417182e24d2b9bbe8ec0de0?d=identicon&s=25 Andy Elvey (latte)
on 2009-02-18 09:47
Hi all - I'm a first-timer and very much love Ruby!

 I have several questions involving arrays. First, I'll create a couple
of arrays to use in my examples -

arr1 = [1, 2, 3, 4, 5]
arr2 = ["foo", "bar", "baz", "abc", "def"]

 What I want to do is the following -
a) I want to create another array that alternates the elements of these
two arrays, like this -
 [1, "foo", 2, "bar", 3, "baz", 4, "abc", 5, "def]

b) In order to be able to create text tables, I'd like a function that
can take a character (like "|") and can apply it to an array so that you
end up with another array like this -
 arr4 = ["|", "foo", "|", "bar", "|", "baz", "|"]

c) Finally, I'd like to create another function to do a very similar
thing to (b), but only have the character *between* the elements, like
this -
 arr5 = ["foo", "|", "bar", "|", "baz"]

 Very many thanks in advance for your help!  (Many thanks to Matz too
for a great language!  :)  )
 - latte
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-18 10:32
Andy Elvey wrote:
>

arr1 = [1, 2, 3, 4, 5]
arr2 = ["foo", "bar", "baz", "abc", "def"]

resultA = arr1.zip(arr2).flatten

resultB = []
arr2.each do |item|
  resultB << "|" << item
end
resultB << "|"

resultC = []
arr2.each do |item|
  resultC << item << "|"
end
resultC.pop()

p resultA
p resultB
p resultC


--output:--
[1, "foo", 2, "bar", 3, "baz", 4, "abc", 5, "def"]
["|", "foo", "|", "bar", "|", "baz", "|", "abc", "|", "def", "|"]
["foo", "|", "bar", "|", "baz", "|", "abc", "|", "def"]
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2009-02-18 10:37
(Received via mailing list)
From: Andy Elvey [mailto:andy.elvey@paradise.net.nz]
# arr1 = [1, 2, 3, 4, 5]
# arr2 = ["foo", "bar", "baz", "abc", "def"]

try #zip

eg,


> arr1.zip(arr2).flatten
=> [1, "foo", 2, "bar", 3, "baz", 4, "abc", 5, "def"]

> Array.new(arr2.size+1,"|").zip(arr2).flatten[0..-2]
=> ["|", "foo", "|", "bar", "|", "baz", "|", "abc", "|", "def", "|"]

> arr2.zip(Array.new(arr2.size-1,"|")).flatten[0..-2]
=> ["foo", "|", "bar", "|", "baz", "|", "abc", "|", "def"]
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-18 10:48
7stud -- wrote:
> arr1 = [1, 2, 3, 4, 5]
> arr2 = ["foo", "bar", "baz", "abc", "def"]
>
> resultA = arr1.zip(arr2).flatten
>

This is probably more efficient:

resultA = []
arr1.zip(arr2) do |item_arr1, item_arr2|
  resultA << item_arr1 << item_arr2
end

Just remember: a bunch of methods chained together on one line is rarely
very efficient.
666b4e17b4bb0e2d999037a25f65a7cb?d=identicon&s=25 Heesob Park (phasis)
on 2009-02-18 11:20
(Received via mailing list)
2009/2/18 7stud -- <bbxx789_05ss@yahoo.com>:
>  resultB << "|" << item
> end
> resultB << "|"
>
You can also write it using inject like this:
arr = arr2.inject(["|"]){|r,e|r<<e<<"|"}

> resultC = []
> arr2.each do |item|
>  resultC << item << "|"
> end
> resultC.pop()
>
arr = arr2.inject([]){|r,e|r<<e<<"I"}
arr.pop

Regards,

Park Heesob
54404bcac0f45bf1c8e8b827cd9bb709?d=identicon&s=25 7stud -- (7stud)
on 2009-02-18 16:08
Heesob Park wrote:
> 2009/2/18 7stud -- <bbxx789_05ss@yahoo.com>:
>>  resultB << "|" << item
>> end
>> resultB << "|"
>>
> You can also write it using inject like this:
> arr = arr2.inject(["|"]){|r,e|r<<e<<"|"}
>

As long as you realize that inject() is always the most inefficient
solution possible.
69f776698d1a63c70af26bfaea085b17?d=identicon&s=25 Choi, Junegunn (Guest)
on 2009-02-18 18:11
(Received via mailing list)
>
> As long as you realize that inject() is always the most inefficient
> solution possible.
>

Can you elaborate on your claim? How inefficient, like, by orders of
magnitude? Is it serious enough to affect the overall performance of a
typical ruby application? In a situation like this, I'd prefer the
code which uses 'inject', since it shows the intention of the
programmer more clearly and concisely, while the performance penalty -
10% in my naive experiment - is irrelevant in this case. I agree that
we should be aware of the performance issues even when we're dealing
with a high-level language such as ruby, but your bold statement makes
me feel that you're trying to 'defend' your own code against the
others in some kind of a code contest.
8f6f95c4bd64d5f10dfddfdcd03c19d6?d=identicon&s=25 Rick Denatale (rdenatale)
on 2009-02-18 19:32
(Received via mailing list)
On Wed, Feb 18, 2009 at 12:10 PM, Choi, Junegunn <jg@samdorr.net> wrote:

> 10% in my naive experiment - is irrelevant in this case. I agree that
> we should be aware of the performance issues even when we're dealing
> with a high-level language such as ruby, but your bold statement makes
> me feel that you're trying to 'defend' your own code against the
> others in some kind of a code contest.
>

I think that the statement that "inject() is always the inefficient
solution
possible", even if it were true, which I'm not at all sure it is, isn't
particularly good advice.

One of my buddy Kent Beck's more well known memes is "Make it run. Make
it
right, Make it fast." [1].  Although the roots of this advice can be
traced
back to Butler Lampson [2].  This advice is something that anyone who
wants
to be a software craftsman needs to take to heart.

The order is important.  First you make sure that the code runs, then
you
need to make it right.  Making it right doesn't  mean that it does the
right
thing, that's a large part of making it run, it mean's making the code
clear
and maintainable, either by you sometime in the future, or by someone
else.
Only then you should make it fast, without unnecessarily harming keeping
it
right.  And the best way to do this is to slavishly follow the 3 rules
of
optimization [3]

While there are some who just seem to hate inject, it can, as you point
out,
be much more intention revealing, which helps in making code right.

This is just one of those things, like when and when not to use optional
parentheses in Ruby which need a bit of thoughtful reflection, rather
than
blind adherence to convention.

[1] http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast
[2]
http://research.microsoft.com/en-us/um/people/blam...
[3] http://c2.com/cgi/wiki?RulesOfOptimization

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Cea563880417182e24d2b9bbe8ec0de0?d=identicon&s=25 Andy Elvey (latte)
on 2009-02-19 07:21
Rick Denatale wrote:
> On Wed, Feb 18, 2009 at 12:10 PM, Choi, Junegunn <jg@samdorr.net> wrote:
>
>> 10% in my naive experiment - is irrelevant in this case. I agree that
>> we should be aware of the performance issues even when we're dealing
>> with a high-level language such as ruby, but your bold statement makes
>> me feel that you're trying to 'defend' your own code against the
>> others in some kind of a code contest.
>>
>
> I think that the statement that "inject() is always the inefficient
> solution possible", even if it were true, which I'm not at all sure it is, isn't 
particularly good advice.
>
> One of my buddy Kent Beck's more well known memes is "Make it run. Make
> it
> right, Make it fast." [1].  Although the roots of this advice can be
> traced
> back to Butler Lampson [2].  This advice is something that anyone who
> wants
> to be a software craftsman needs to take to heart.

 ( snip )

 Great! Oh, and please forgive me for snipping a few lines here, Rick -
I got an automated message telling me to reduce the number of quoted
lines.

Thanks Rick, and a very big **thank you** to everyone else who has
replied here!  It's great to be part of such an active, friendly and
generous community!

Bye for now - :-)
- latte
This topic is locked and can not be replied to.