Newbie - several array questions


#1

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! :slight_smile: )

  • latte

#2

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”]


#3

From: Andy Elvey [mailto:removed_email_address@domain.invalid]

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”]


#4

2009/2/18 7stud – removed_email_address@domain.invalid:

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 H.


#5

Heesob P. wrote:

2009/2/18 7stud – removed_email_address@domain.invalid:

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.


#6

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.


#7

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.


#8

On Wed, Feb 18, 2009 at 12:10 PM, Choi, Junegunn removed_email_address@domain.invalid 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/blampson/33-hints/webpage.html
[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


#9

Rick Denatale wrote:

On Wed, Feb 18, 2009 at 12:10 PM, Choi, Junegunn removed_email_address@domain.invalid 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 - :slight_smile:

  • latte