Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > find index of first non zeo value in array

Reply
Thread Tools

find index of first non zeo value in array

 
 
Josselin
Guest
Posts: n/a
 
      11-26-2006
with :
array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0]

I wrote :
array.index(array.detect {|x| x > 0}) => 15

is there a better and simpler way to do it ?
thanks

joss

 
Reply With Quote
 
 
 
 
Olivier
Guest
Posts: n/a
 
      11-26-2006
Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit=A0:
> with :
> array =3D [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0,
> 0, 0, 0, 0, 0, 0]
>
> I wrote :
> array.index(array.detect {|x| x > 0}) =3D> 15
>
> is there a better and simpler way to do it ?
> thanks
>
> joss


In that case, it is simpler to use an external counter, i think :

c =3D 0
array.each{|v| break if not v.zero?; c +=3D 1}
puts c # =3D> 15

 
Reply With Quote
 
 
 
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-26-2006
---2049402039-511287211-1164554586=:11709
Content-Type: MULTIPART/MIXED; BOUNDARY="-2049402039-511287211-1164554586=:11709"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---2049402039-511287211-1164554586=:11709
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Sun, 26 Nov 2006, Olivier wrote:

> Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit=A0:
>> with :
>> array =3D [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0,
>> 0, 0, 0, 0, 0, 0]
>>
>> I wrote :
>> array.index(array.detect {|x| x > 0}) =3D> 15
>>
>> is there a better and simpler way to do it ?
>> thanks
>>
>> joss

>
> In that case, it is simpler to use an external counter, i think :
>
> c =3D 0
> array.each{|v| break if not v.zero?; c +=3D 1}
> puts c # =3D> 15


Or:

c =3D array.each_with_index {|e,i| break i unless e.zero? }


David

--=20
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
---2049402039-511287211-1164554586=:11709--
---2049402039-511287211-1164554586=:11709--

 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-26-2006
On Mon, 27 Nov 2006, wrote:

> Or:
>
> c = array.each_with_index {|e,i| break i unless e.zero? }


No, I'm wrong; that leaves c == a if there's no non-zero element.
Ignore.


David

--
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      11-26-2006
On Nov 26, 2006, at 8:54 AM, Olivier wrote:

> Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit :
>> with :
>> array =3D [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, =

0,
>> 0, 0, 0, 0, 0, 0]
>>
>> I wrote :
>> array.index(array.detect {|x| x > 0}) =3D> 15
>>
>> is there a better and simpler way to do it ?
>> thanks
>>
>> joss

>
> In that case, it is simpler to use an external counter, i think :
>
> c =3D 0
> array.each{|v| break if not v.zero?; c +=3D 1}
> puts c # =3D> 15


You can ask Ruby to maintain the counter, if you want:

>> require "enumerator"

=3D> true
>> array =3D [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, =20=


0, 0,
?> 0, 0, 0, 0, 0, 0]
=3D> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, =20=

0, 0, 0, 0, 0]
>> result =3D array.enum_with_index.find { |n, i| n.nonzero? }.last =20

rescue nil
=3D> 15
>> array.slice!(15, 1)

=3D> [21]
>> array

=3D> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, =20=

0, 0, 0]
>> result =3D array.enum_with_index.find { |n, i| n.nonzero? }.last =20

rescue nil
=3D> nil

James Edward Gray II=

 
Reply With Quote
 
Park Heesob
Guest
Posts: n/a
 
      11-26-2006

Hi,

>From: Josselin <>
>Reply-To: ruby-
>To: ruby- (ruby-talk ML)
>Subject: find index of first non zeo value in array
>Date: Sun, 26 Nov 2006 23:00:10 +0900
>
>with :
>array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0,
>0, 0, 0, 0]
>
>I wrote :
>array.index(array.detect {|x| x > 0}) => 15
>
>is there a better and simpler way to do it ?
>thanks
>
>joss
>
>

How about this:

array.index((array-[0])[0])

Regards,

Park Heesob

__________________________________________________ _______________
Don't just search. Find. Check out the new MSN Search!
http://search.msn.com/


 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-26-2006
---2049402039-1184309673-1164556388=:11991
Content-Type: MULTIPART/MIXED; BOUNDARY="-2049402039-1184309673-1164556388=:11991"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---2049402039-1184309673-1164556388=:11991
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Mon, 27 Nov 2006, James Edward Gray II wrote:

> On Nov 26, 2006, at 8:54 AM, Olivier wrote:
>
>> Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit :
>>>
>>> array.index(array.detect {|x| x > 0}) =3D> 15

>>=20
>> c =3D 0
>> array.each{|v| break if not v.zero?; c +=3D 1}
>> puts c # =3D> 15

>
>>> result =3D array.enum_with_index.find { |n, i| n.nonzero? }.last rescue=

nil

That seems kind of like a reinvention of Array#index, though. It also
has the usual problem with rescue, i.e., that you might rescue the
wrong thing (if nonzero? is mistyped or whatever). Do you see an
advantage to doing it this way, rather than the index/detect way?
(I'm being lazy and not benchmarking them....)


David

--=20
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
---2049402039-1184309673-1164556388=:11991--
---2049402039-1184309673-1164556388=:11991--

 
Reply With Quote
 
James Edward Gray II
Guest
Posts: n/a
 
      11-26-2006
On Nov 26, 2006, at 9:53 AM, wrote:

> On Mon, 27 Nov 2006, James Edward Gray II wrote:
>
>> On Nov 26, 2006, at 8:54 AM, Olivier wrote:
>>
>>> Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit :
>>>>
>>>> array.index(array.detect {|x| x > 0}) =3D> 15
>>> c =3D 0
>>> array.each{|v| break if not v.zero?; c +=3D 1}
>>> puts c # =3D> 15

>>
>>>> result =3D array.enum_with_index.find { |n, i| n.nonzero? }.last =20=


>>>> rescue nil

>
> That seems kind of like a reinvention of Array#index, though. It also
> has the usual problem with rescue, i.e., that you might rescue the
> wrong thing (if nonzero? is mistyped or whatever). Do you see an
> advantage to doing it this way, rather than the index/detect way?
> (I'm being lazy and not benchmarking them....)


Well, it only walks the Array once. The other way walks it once for =20
detect() and again for index(). I agree that it's not sexy code though.

I believe there has been talk in the past of having index() take a =20
block for matching. That would solve this problem ideally. I can =20
submit an RCR if people think it's worth it, but I'm pretty sure Matz =20=

said it was OK last time it came up... (Correct me if I am wrong!)

James Edward Gray II


 
Reply With Quote
 
dblack@wobblini.net
Guest
Posts: n/a
 
      11-26-2006
---2049402039-103646226-1164557367=:12154
Content-Type: MULTIPART/MIXED; BOUNDARY="-2049402039-103646226-1164557367=:12154"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

---2049402039-103646226-1164557367=:12154
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Mon, 27 Nov 2006, James Edward Gray II wrote:

> On Nov 26, 2006, at 9:53 AM, wrote:
>
>> On Mon, 27 Nov 2006, James Edward Gray II wrote:
>>=20
>>> On Nov 26, 2006, at 8:54 AM, Olivier wrote:
>>>=20
>>>> Le dimanche 26 novembre 2006 15:00, Josselin a =E9crit :
>>>>>=20
>>>>> array.index(array.detect {|x| x > 0}) =3D> 15
>>>> c =3D 0
>>>> array.each{|v| break if not v.zero?; c +=3D 1}
>>>> puts c # =3D> 15
>>>=20
>>>>> result =3D array.enum_with_index.find { |n, i| n.nonzero? }.last resc=

ue=20
>>>>> nil

>>=20
>> That seems kind of like a reinvention of Array#index, though. It also
>> has the usual problem with rescue, i.e., that you might rescue the
>> wrong thing (if nonzero? is mistyped or whatever). Do you see an
>> advantage to doing it this way, rather than the index/detect way?
>> (I'm being lazy and not benchmarking them....)

>
> Well, it only walks the Array once. The other way walks it once for dete=

ct()=20
> and again for index(). I agree that it's not sexy code though.
>
> I believe there has been talk in the past of having index() take a block =

for=20
> matching. That would solve this problem ideally. I can submit an RCR if=

=20
> people think it's worth it, but I'm pretty sure Matz said it was OK last =

time=20
> it came up... (Correct me if I am wrong!)


Yes, there's an accepted RCR for it. That will be good.

This exchange relates to something I've been pondering for a while,
namely: is there always (or very, very often) an inverse relation
between elegance of code and efficiency? I don't mean to sound like
I'm singling out your example -- on the contrary, it seems that over
and over we see cases where a nice concise solution bombs out compared
to one that's longer, possibly less clear (I still can't read the
enum* stuff as quickly and confidently as I can read the regular
Enumerable stuff, though that may just be due to stupidity), but
faster.

I haven't really documented or studied this in detail, though it does
seem to keep happening. It might be interesting to look into further.


David

--=20
David A. Black |
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
---2049402039-103646226-1164557367=:12154--
---2049402039-103646226-1164557367=:12154--

 
Reply With Quote
 
Devin Mullins
Guest
Posts: n/a
 
      11-26-2006
James Edward Gray II wrote:
> I believe there has been talk in the past of having index() take a
> block for matching.

Meh... talk schmalk...

class Array
alias orig_index index
def index(*args)
return orig_index(*args) unless block_given?
(0...length).each do |i|
return i if yield self[i]
end
nil
end
end

array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0]
array.index 21 #=> 15
array.index {|n| n.nonzero? } #=> 15

Devin


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Making an array wrap, where last index + 1 = first index Shawn W_ Ruby 5 09-16-2009 02:45 PM
sorting index-15, index-9, index-110 "the human way"? Tomasz Chmielewski Perl Misc 4 03-04-2008 05:01 PM
IndexedCatalog and ZEO Almad Python 4 03-07-2005 11:42 PM
More ZEO/ZODB issues drs Python 0 07-12-2003 12:41 AM
ZEO and COM drs Python 0 07-11-2003 08:41 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57