# A better way to do this job?

**URL:** <https://rubytalk.org/t/a-better-way-to-do-this-job/51653>\
**Category:** ruby-talk\
**Created:** [10 February 2009 09:11 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653 "2009-02-10T09:11:28Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zhenning\_Guan](https://avatars.discourse-cdn.com/v4/letter/z/85e7bf/32.png) [@Zhenning\_Guan](https://rubytalk.org/u/Zhenning_Guan)\
**Post date:** [10 February 2009 09:11 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/1 "2009-02-10T09:11:28Z")

</div>

topics.each do |f|  
&nbsp;&nbsp;times +=1  
&nbsp;&nbsp;puts f.title  
&nbsp;&nbsp;if times \> 4  
&nbsp;&nbsp;&nbsp;&nbsp;break

a little ugly, doesn't it?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Stefano\_Crocco](https://avatars.discourse-cdn.com/v4/letter/s/5f9b8f/32.png) [@Stefano\_Crocco](https://rubytalk.org/u/Stefano_Crocco)\
**Post date:** [10 February 2009 09:15 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/2 "2009-02-10T09:15:50Z")

</div>

Alle Tuesday 10 February 2009, Zhenning Guan ha scritto:

> topics.each do |f|  
> &nbsp;&nbsp;times +=1  
> &nbsp;&nbsp;puts f.title  
> &nbsp;&nbsp;if times \> 4  
> &nbsp;&nbsp;&nbsp;&nbsp;break
> 
> a little ugly, doesn't it?

If topics is an array, you can use:

topics[0..4].each{|f| puts f.title}

Another option, which can be used for any Enumerable object is:

topics.each\_with\_index do |f, i|  
&nbsp;&nbsp;puts f.title  
&nbsp;&nbsp;break if i \> 4  
end

While not as nice as the first version, it's a bit clearer than your code.

I hope this helps

Stefano

---

<div class="post-metadata">

**Author:** ![Jesus\_Gabriel\_y\_Gala](https://avatars.discourse-cdn.com/v4/letter/j/96bed5/32.png) [@Jesus\_Gabriel\_y\_Gala](https://rubytalk.org/u/Jesus_Gabriel_y_Gala)\
**Post date:** [10 February 2009 09:18 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/3 "2009-02-10T09:18:32Z")

</div>

topics[0,5].each do |f|  
&nbsp;&nbsp;&nbsp;puts f.title  
end

# if you need the variable "times" to have the same value as above:  
# times = topics[0,5].size

Jesus.

> **···**
>
> On Tue, Feb 10, 2009 at 10:11 AM, Zhenning Guan \<g.zhen.ning@gmail.com\> wrote:
> 
> > topics.each do |f|  
> > times +=1  
> > puts f.title  
> > if times \> 4  
> > &nbsp;&nbsp;&nbsp;break
> > 
> > a little ugly, doesn't it?

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [10 February 2009 11:30 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/4 "2009-02-10T11:30:09Z")

</div>

there are a lot of ways. My first reaction is:

&nbsp;&nbsp;&nbsp;topics.first(5).each do |f|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts f.title  
&nbsp;&nbsp;&nbsp;end

If you define to\_s on the topic class to return title then you can do:

&nbsp;&nbsp;&nbsp;puts topics.first(5)

and be done with it.

> **···**
>
> On Feb 10, 2009, at 01:11 , Zhenning Guan wrote:
> 
> > topics.each do |f|  
> > times +=1  
> > puts f.title  
> > if times \> 4  
> > &nbsp;&nbsp;&nbsp;break

---

<div class="post-metadata">

**Author:** ![7stud](https://avatars.discourse-cdn.com/v4/letter/7/57b2e6/32.png) [@7stud](https://rubytalk.org/u/7stud)\
**Post date:** [10 February 2009 11:37 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/5 "2009-02-10T11:37:58Z")

</div>

Zhenning Guan wrote:

> topics.each do |f|  
> &nbsp;&nbsp;times +=1  
> &nbsp;&nbsp;puts f.title  
> &nbsp;&nbsp;if times \> 4  
> &nbsp;&nbsp;&nbsp;&nbsp;break
> 
> > Another option, which can be used for any Enumerable object is:
> > 
> > topics.each\_with\_index do |f, i|  
> > &nbsp;&nbsp;puts f.title  
> > &nbsp;&nbsp;break if i \> 4  
> > end
> > 
> > While not as nice as the first version, it's a bit clearer than your  
> > code.

In my opinion, it's nicer than the first version because it doesn't have  
to create a sub array in memory, like all the solutions posted so far  
do, which could be a problem with large arrays and large slices.

4.times do |i|  
&nbsp;&nbsp;puts topics[i].title  
end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Julian\_Leviston](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@Julian\_Leviston](https://rubytalk.org/u/Julian_Leviston)\
**Post date:** [10 February 2009 12:17 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/6 "2009-02-10T12:17:28Z")

</div>

Your code also won't work. Your tempvar is not declared and you have no end to the block.

topics[0..3].each do |topic|  
puts topic  
end

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

> **···**
>
> On 10/02/2009, at 8:11 PM, Zhenning Guan \<g.zhen.ning@gmail.com\> wrote:
> 
> > topics.each do |f|  
> > times +=1  
> > puts f.title  
> > if times \> 4  
> > &nbsp;&nbsp;&nbsp;break
> > 
> > a little ugly, doesn't it?  
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Christopher\_Dicely](https://avatars.discourse-cdn.com/v4/letter/c/7c8e57/32.png) [@Christopher\_Dicely](https://rubytalk.org/u/Christopher_Dicely)\
**Post date:** [11 February 2009 02:02 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/7 "2009-02-11T02:02:16Z")

</div>

Assuming there is a times=0 before this, and what you want to do is  
print each topic title if there are 5 or less topics, but only those 5  
if there are more, then:

topics[0..4].each {|f| puts f.title}

or:

topics.each\_with\_index do |f, i|  
&nbsp;&nbsp;puts f.title  
&nbsp;&nbsp;break if i \> 4  
end

is probably the best way to do it (the first is, IMO, cleaner and more  
understandable, the latter seems like it would somewhat more efficient  
because it doesn't create an auxiliary array, though for this size it  
doesn't matter, it conceivably might for very large arrays.)

5.times {|i| puts topics[i].title}

works if there are 5 or more topics, but will dump nils at the end if  
there are less than 5.

> **···**
>
> On Tue, Feb 10, 2009 at 1:11 AM, Zhenning Guan \<g.zhen.ning@gmail.com\> wrote:
> 
> > topics.each do |f|  
> > times +=1  
> > puts f.title  
> > if times \> 4  
> > &nbsp;&nbsp;&nbsp;break
> > 
> > a little ugly, doesn't it?

---

<div class="post-metadata">

**Author:** ![Julian\_Leviston](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@Julian\_Leviston](https://rubytalk.org/u/Julian_Leviston)\
**Post date:** [10 February 2009 12:21 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/8 "2009-02-10T12:21:40Z")

</div>

First doesn't take an argument I'm ruby. It does  
If you're using rails enumerable mixin

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

> **···**
>
> On 10/02/2009, at 10:30 PM, Ryan Davis \<ryand-ruby@zenspider.com\> wrote:
> 
> > On Feb 10, 2009, at 01:11 , Zhenning Guan wrote:
> > 
> > > topics.each do |f|  
> > > times +=1  
> > > puts f.title  
> > > if times \> 4  
> > > &nbsp;&nbsp;break
> > 
> > there are a lot of ways. My first reaction is:
> > 
> > topics.first(5).each do |f|  
> > &nbsp;&nbsp;&nbsp;puts f.title  
> > end
> > 
> > If you define to\_s on the topic class to return title then you can do:
> > 
> > puts topics.first(5)
> > 
> > and be done with it.

---

<div class="post-metadata">

**Author:** ![Julian\_Leviston](https://avatars.discourse-cdn.com/v4/letter/j/b5a626/32.png) [@Julian\_Leviston](https://rubytalk.org/u/Julian_Leviston)\
**Post date:** [10 February 2009 12:29 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/9 "2009-02-10T12:29:43Z")

</div>

Slices and 'sub-arrays' aren't copies of the objects, they simply refer to the identical objects.

Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

> **···**
>
> On 10/02/2009, at 10:37 PM, 7stud -- \<bbxx789\_05ss@yahoo.com\> wrote:
> 
> > Zhenning Guan wrote:
> > 
> > > topics.each do |f|  
> > > times +=1  
> > > puts f.title  
> > > if times \> 4  
> > > &nbsp;&nbsp;&nbsp;break
> > > 
> > > > Another option, which can be used for any Enumerable object is:
> > > > 
> > > > topics.each\_with\_index do |f, i|  
> > > > puts f.title  
> > > > break if i \> 4  
> > > > end
> > > > 
> > > > While not as nice as the first version, it's a bit clearer than your  
> > > > code.
> > 
> > In my opinion, it's nicer than the first version because it doesn't have  
> > to create a sub array in memory, like all the solutions posted so far  
> > do, which could be a problem with large arrays and large slices.
> > 
> > 4.times do |i|  
> > puts topics[i].title  
> > end
> > 
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [10 February 2009 12:53 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/10 "2009-02-10T12:53:32Z")

</div>

Hi --

> In my opinion, it's nicer than the first version because it doesn't have  
> to create a sub array in memory, like all the solutions posted so far  
> do, which could be a problem with large arrays and large slices.

Ryan had something like:

&nbsp;&nbsp;&nbsp;topics.first(5).each do |t|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts t.title  
&nbsp;&nbsp;&nbsp;end

which, I believe, does not create an intermediate array because  
topics.first(5) returns an enumerator.

David

> **···**
>
> On Tue, 10 Feb 2009, 7stud -- wrote:
> 
> --  
> David A. Black / Ruby Power and Light, LLC  
> Ruby/Rails consulting & training: [http://www.rubypal.com](http://www.rubypal.com)  
> Coming in 2009: The Well-Grounded Rubyist ([http://manning.com/black2\](http://manning.com/black2%5C))
> 
> [http://www.wishsight.com](http://www.wishsight.com) =\> Independent, social wishlist management!

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [10 February 2009 20:08 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/11 "2009-02-10T20:08:38Z")

</div>

mentarbation.

it isn't a problem until it is a problem.

> **···**
>
> On Feb 10, 2009, at 03:37 , 7stud -- wrote:
> 
> > In my opinion, it's nicer than the first version because it doesn't have  
> > to create a sub array in memory, like all the solutions posted so far  
> > do, which could be a problem with large arrays and large slices.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [10 February 2009 12:45 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/12 "2009-02-10T12:45:12Z")

</div>

Hi --

> **···**
>
> On Tue, 10 Feb 2009, Julian Leviston wrote:
> 
> > First doesn't take an argument I'm ruby. It does  
> > If you're using rails enumerable mixin
> 
> $ ruby19 -ve 'puts [1,2,3,4].first(2)'  
> ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]  
> 1  
> 2
> 
> David
> 
> --  
> David A. Black / Ruby Power and Light, LLC  
> Ruby/Rails consulting & training: [http://www.rubypal.com](http://www.rubypal.com)  
> Coming in 2009: The Well-Grounded Rubyist ([http://manning.com/black2\](http://manning.com/black2%5C))
> 
> [http://www.wishsight.com](http://www.wishsight.com) =\> Independent, social wishlist management!

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [10 February 2009 12:51 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/13 "2009-02-10T12:51:30Z")

</div>

Hi --

> **···**
>
> On Tue, 10 Feb 2009, Julian Leviston wrote:
> 
> > Slices and 'sub-arrays' aren't copies of the objects, they simply refer to the identical objects.
> 
> The same can be said of any array; the objects inside it exist (in  
> many cases, at least) already. Still, container objects do take up  
> memory. If you don't believe it, try this:
> 
> &nbsp;&nbsp;&nbsp;ruby -e 'a = [:a,:b,:c]; b = ; while true; b \<\< a[0,3]; end'
> 
> David
> 
> --  
> David A. Black / Ruby Power and Light, LLC  
> Ruby/Rails consulting & training: [http://www.rubypal.com](http://www.rubypal.com)  
> Coming in 2009: The Well-Grounded Rubyist ([http://manning.com/black2\](http://manning.com/black2%5C))
> 
> [http://www.wishsight.com](http://www.wishsight.com) =\> Independent, social wishlist management!

---

<div class="post-metadata">

**Author:** ![James\_Edward\_Gray\_II](https://avatars.discourse-cdn.com/v4/letter/j/ea5d25/32.png) [@James\_Edward\_Gray\_II](https://rubytalk.org/u/James_Edward_Gray_II)\
**Post date:** [10 February 2009 13:59 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/14 "2009-02-10T13:59:41Z")

</div>

Would you please stop top posting? It's just bad manners.

James Edward Gray II

> **···**
>
> On Feb 10, 2009, at 6:21 AM, Julian Leviston wrote:
> 
> > First doesn't take an argument I'm ruby. It does  
> > If you're using rails enumerable mixin
> > 
> > Blog: [http://random8.zenunit.com/](http://random8.zenunit.com/)  
> > Learn rails: [http://sensei.zenunit.com/](http://sensei.zenunit.com/)

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [10 February 2009 14:01 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/15 "2009-02-10T14:01:19Z")

</div>

Hi --

> **···**
>
> On Tue, 10 Feb 2009, David A. Black wrote:
> 
> > Hi --
> > 
> > On Tue, 10 Feb 2009, 7stud -- wrote:
> > 
> > > In my opinion, it's nicer than the first version because it doesn't have  
> > > to create a sub array in memory, like all the solutions posted so far  
> > > do, which could be a problem with large arrays and large slices.
> > 
> > Ryan had something like:
> > 
> > topics.first(5).each do |t|  
> > &nbsp;&nbsp;&nbsp;puts t.title  
> > end
> > 
> > which, I believe, does not create an intermediate array because  
> > topics.first(5) returns an enumerator.
> 
> Rewind. As Tom points out, first(x) returns an array. (Which in fact  
> makes sense, since it's often used entirely on its own.)
> 
> David
> 
> --  
> David A. Black / Ruby Power and Light, LLC  
> Ruby/Rails consulting & training: [http://www.rubypal.com](http://www.rubypal.com)  
> Coming in 2009: The Well-Grounded Rubyist ([http://manning.com/black2\](http://manning.com/black2%5C))
> 
> [http://www.wishsight.com](http://www.wishsight.com) =\> Independent, social wishlist management!

---

<div class="post-metadata">

**Author:** ![7stud](https://avatars.discourse-cdn.com/v4/letter/7/57b2e6/32.png) [@7stud](https://rubytalk.org/u/7stud)\
**Post date:** [10 February 2009 15:28 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/16 "2009-02-10T15:28:37Z")

</div>

Julian Leviston wrote:

> Slices and 'sub-arrays' aren't copies of the objects, they simply  
> refer to the identical objects.

Is it your opinion that an array of pointers takes up no memory? Which  
takes up more memory: an array of int's or an array of pointers?

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [10 February 2009 20:06 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/17 "2009-02-10T20:06:21Z")

</div>

David showed it in 1.9... but I had to point this out:

% ruby -ve 'puts [1,2,3,4].first(2)'  
ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]  
1  
2

this goes back to at least 1.7 iirc. #first was introduced in 1.6 and 1.7 gave it an optional length arg.

> **···**
>
> On Feb 10, 2009, at 04:21 , Julian Leviston wrote:
> 
> > First doesn't take an argument I'm ruby. It does  
> > If you're using rails enumerable mixin

---

<div class="post-metadata">

**Author:** ![ThoML](https://avatars.discourse-cdn.com/v4/letter/t/d78d45/32.png) [@ThoML](https://rubytalk.org/u/ThoML)\
**Post date:** [10 February 2009 13:14 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/18 "2009-02-10T13:14:46Z")

</div>

> ruby -e 'a = [:a,:b,:c]; b = ; while true; b \<\< a[0,3]; end'

That's a little bit unfair though. If you pushed an infinite number of  
object of whatever class, you'd eventually run out of memory.

I personally find #first() rather confusing (BTW [1,2,3].first  
(3).class =\> Array). I'd rather prefer [0..4] (although [0,5] should  
perform slightly better) or maybe #each\_index, which doesn't create an  
intermediary array. #each\_index would also have the advantage that it  
expects only an Enumerable.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [10 February 2009 16:32 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/19 "2009-02-10T16:32:33Z")

</div>

Well, an array of Fixnums takes up the same space as an array of 'pointers'  
to Fixnums, since Fixnums are immediate.

> **···**
>
> On Tue, Feb 10, 2009 at 10:28 AM, 7stud -- \<bbxx789\_05ss@yahoo.com\> wrote:
> 
> > Julian Leviston wrote:  
> > \> Slices and 'sub-arrays' aren't copies of the objects, they simply  
> > \> refer to the identical objects.  
> > \>
> > 
> > Is it your opinion that an array of pointers takes up no memory? Which  
> > takes up more memory: an array of int's or an array of pointers?
> 
> --  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Twitter: [http://twitter.com/RickDeNatale](http://twitter.com/RickDeNatale)

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [10 February 2009 20:07 UTC](https://rubytalk.org/t/a-better-way-to-do-this-job/51653/20 "2009-02-10T20:07:07Z")

</div>

agreed!

> **···**
>
> On Feb 10, 2009, at 05:59 , James Gray wrote:
> 
> > On Feb 10, 2009, at 6:21 AM, Julian Leviston wrote:
> > 
> > > First doesn't take an argument I'm ruby. It does  
> > > If you're using rails enumerable mixin
> > 
> > Would you please stop top posting? It's just bad manners.

[Next page](https://rubytalk.org/t/a-better-way-to-do-this-job/51653.md?page=2)
