Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Array::index and rindex operator

Reply
Thread Tools

Array::index and rindex operator

 
 
Hadmut Danisch
Guest
Posts: n/a
 
      07-05-2004
Hi,

the Array::index and rindex functions

arr.index( anObject ) -> anInteger or nil
Return the index of the first/last object in arr such that the
object == anObject. Returns nil if no match is found.



Wouldn't it be better to have

such that anObject === object ?

regards
Hadmut
 
Reply With Quote
 
 
 
 
George Ogata
Guest
Posts: n/a
 
      07-05-2004
Hadmut Danisch <(E-Mail Removed)> writes:

> Hi,
>
> the Array::index and rindex functions
>
> arr.index( anObject ) -> anInteger or nil
> Return the index of the first/last object in arr such that the
> object == anObject. Returns nil if no match is found.
>
>
>
> Wouldn't it be better to have
>
> such that anObject === object ?



I'm not so sure about that; #=== is primarily meant for case
statements, and very few methods use it like the way you propose. It
would also separate it from other Array/Enumerable methods like #find,
#delete, #include?, etc.

Sometimes though I wish that #index could take a block (i.e., return
the first index for which the block is true). Unless I'm overlooking
something, there doesn't seem to be a method that does this. I don't
know what others think of the idea, but that would probably go some
way towards your goal.
 
Reply With Quote
 
 
 
 
Joel VanderWerf
Guest
Posts: n/a
 
      07-05-2004
George Ogata wrote:
> Hadmut Danisch <(E-Mail Removed)> writes:
>
>
>>Hi,
>>
>>the Array::index and rindex functions
>>
>> arr.index( anObject ) -> anInteger or nil
>> Return the index of the first/last object in arr such that the
>> object == anObject. Returns nil if no match is found.
>>
>>
>>
>>Wouldn't it be better to have
>>
>> such that anObject === object ?

>
>
>
> I'm not so sure about that; #=== is primarily meant for case
> statements, and very few methods use it like the way you propose. It
> would also separate it from other Array/Enumerable methods like #find,
> #delete, #include?, etc.
>
> Sometimes though I wish that #index could take a block (i.e., return
> the first index for which the block is true). Unless I'm overlooking
> something, there doesn't seem to be a method that does this. I don't
> know what others think of the idea, but that would probably go some
> way towards your goal.


Enumerable#grep does use #===, so maybe what the OP wants is something
like grep but instead of returning the matching value returns the index.


 
Reply With Quote
 
Kristof Bastiaensen
Guest
Posts: n/a
 
      07-06-2004
Hi,

On Tue, 06 Jul 2004 09:42:41 +1000, George Ogata wrote:

> Sometimes though I wish that #index could take a block (i.e., return
> the first index for which the block is true). Unless I'm overlooking
> something, there doesn't seem to be a method that does this. I don't
> know what others think of the idea, but that would probably go some
> way towards your goal.


I think that would be nice. I would vote for it.
You could do this with enumerator, but it is not so compact:

require "enumerator"

a = %w(one two three)
a.enum_for(:each_with_index).find { |s, i| s == "two" }[1]
=> 1

Regards,
Kristof
 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-06-2004

"Kristof Bastiaensen" <(E-Mail Removed)> schrieb im Newsbeitrag
news(E-Mail Removed).. .
> Hi,
>
> On Tue, 06 Jul 2004 09:42:41 +1000, George Ogata wrote:
>
> > Sometimes though I wish that #index could take a block (i.e., return
> > the first index for which the block is true). Unless I'm overlooking
> > something, there doesn't seem to be a method that does this. I don't
> > know what others think of the idea, but that would probably go some
> > way towards your goal.

>
> I think that would be nice. I would vote for it.
> You could do this with enumerator, but it is not so compact:
>
> require "enumerator"
>
> a = %w(one two three)
> a.enum_for(:each_with_index).find { |s, i| s == "two" }[1]
> => 1


Another solution:

a.inject(0) {|i,s| break i if "two" == s; idx+1}

#inject is just great!

Regards

robert

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      07-06-2004
Hi --

On Tue, 6 Jul 2004, Robert Klemme wrote:

>
> "Kristof Bastiaensen" <(E-Mail Removed)> schrieb im Newsbeitrag
> news(E-Mail Removed).. .
> > Hi,
> >
> > On Tue, 06 Jul 2004 09:42:41 +1000, George Ogata wrote:
> >
> > > Sometimes though I wish that #index could take a block (i.e., return
> > > the first index for which the block is true). Unless I'm overlooking
> > > something, there doesn't seem to be a method that does this. I don't
> > > know what others think of the idea, but that would probably go some
> > > way towards your goal.

> >
> > I think that would be nice. I would vote for it.
> > You could do this with enumerator, but it is not so compact:
> >
> > require "enumerator"
> >
> > a = %w(one two three)
> > a.enum_for(:each_with_index).find { |s, i| s == "two" }[1]
> > => 1

>
> Another solution:
>
> a.inject(0) {|i,s| break i if "two" == s; idx+1}


The problem though (aside from 'idx' for 'i' is that you always
get a number, even if there's no element found:

[1,2,3].inject(0) {|i,s| break i if "two" == s; i + 1}

# => 3


David

--
David A. Black
http://www.velocityreviews.com/forums/(E-Mail Removed)



 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-06-2004

"David A. Black" <(E-Mail Removed)> schrieb im Newsbeitrag
newsine.LNX.4.44.0407060521080.8383-100000@wobblini...
> Hi --
>
> On Tue, 6 Jul 2004, Robert Klemme wrote:
>
> >
> > "Kristof Bastiaensen" <(E-Mail Removed)> schrieb im Newsbeitrag
> > news(E-Mail Removed).. .
> > > Hi,
> > >
> > > On Tue, 06 Jul 2004 09:42:41 +1000, George Ogata wrote:
> > >
> > > > Sometimes though I wish that #index could take a block (i.e.,

return
> > > > the first index for which the block is true). Unless I'm

overlooking
> > > > something, there doesn't seem to be a method that does this. I

don't
> > > > know what others think of the idea, but that would probably go

some
> > > > way towards your goal.
> > >
> > > I think that would be nice. I would vote for it.
> > > You could do this with enumerator, but it is not so compact:
> > >
> > > require "enumerator"
> > >
> > > a = %w(one two three)
> > > a.enum_for(:each_with_index).find { |s, i| s == "two" }[1]
> > > => 1

> >
> > Another solution:
> >
> > a.inject(0) {|i,s| break i if "two" == s; idx+1}

>
> The problem though (aside from 'idx' for 'i'


Thanks for that correction!

> is that you always
> get a number, even if there's no element found:
>
> [1,2,3].inject(0) {|i,s| break i if "two" == s; i + 1}
>
> # => 3


True. The approach is betters suited to a method implementation:

module Enumerable
def index_2(obj=nil, &b)
b = lambda {|x| obj == x} unless b
inject(0) {|i,el| return i if b.call(el); i+1}
nil
end
end

Thx for correcting my sloppyness.

robert


 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      07-06-2004
Hi --

On Tue, 6 Jul 2004, Robert Klemme wrote:

> True. The approach is betters suited to a method implementation:
>
> module Enumerable
> def index_2(obj=nil, &b)
> b = lambda {|x| obj == x} unless b
> inject(0) {|i,el| return i if b.call(el); i+1}
> nil
> end
> end


I agree. My version, for what it's worth, was:

module Enumerable
def b_index
each_with_index {|e,i| return i if yield(e) }
nil
end
end

I decided to make it orthogonal to #index, rather than a superset of
it, on the theory that it would be good to avoid making it legal to
give both an argument and a block. I also like #each_with_index
here, rather than #inject, only because it does more of the work and
eliminates the need for manually incrementing an index. I haven't
benchmarked them though.


David

--
David A. Black
(E-Mail Removed)



 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-06-2004

"David A. Black" <(E-Mail Removed)> schrieb im Newsbeitrag
newsine.LNX.4.44.0407060654550.23516-100000@wobblini...
> Hi --
>
> On Tue, 6 Jul 2004, Robert Klemme wrote:
>
> > True. The approach is betters suited to a method implementation:
> >
> > module Enumerable
> > def index_2(obj=nil, &b)
> > b = lambda {|x| obj == x} unless b
> > inject(0) {|i,el| return i if b.call(el); i+1}
> > nil
> > end
> > end

>
> I agree. My version, for what it's worth, was:
>
> module Enumerable
> def b_index
> each_with_index {|e,i| return i if yield(e) }
> nil
> end
> end
>
> I decided to make it orthogonal to #index, rather than a superset of
> it, on the theory that it would be good to avoid making it legal to
> give both an argument and a block.


Might be best to just enhance #index with the block variant.

> I also like #each_with_index
> here, rather than #inject, only because it does more of the work and
> eliminates the need for manually incrementing an index. I haven't
> benchmarked them though.


True. I was blind for that because of my strong #inject affection...

Regards

robert

 
Reply With Quote
 
David A. Black
Guest
Posts: n/a
 
      07-06-2004
Hi --

On Wed, 7 Jul 2004, Robert Klemme wrote:

>
> "David A. Black" <(E-Mail Removed)> schrieb im Newsbeitrag
> newsine.LNX.4.44.0407060654550.23516-100000@wobblini...
> > Hi --
> >
> > On Tue, 6 Jul 2004, Robert Klemme wrote:
> >
> > > True. The approach is betters suited to a method implementation:
> > >
> > > module Enumerable
> > > def index_2(obj=nil, &b)
> > > b = lambda {|x| obj == x} unless b
> > > inject(0) {|i,el| return i if b.call(el); i+1}
> > > nil
> > > end
> > > end

> >
> > I agree. My version, for what it's worth, was:
> >
> > module Enumerable
> > def b_index
> > each_with_index {|e,i| return i if yield(e) }
> > nil
> > end
> > end
> >
> > I decided to make it orthogonal to #index, rather than a superset of
> > it, on the theory that it would be good to avoid making it legal to
> > give both an argument and a block.

>
> Might be best to just enhance #index with the block variant.


What stumped me was: given this:

ary.index(x) {|e| <condition> }

which behavior would you expect? Or would it raise an exception? I
couldn't decide which would be best, which is what led me to a new
method. I can't remember whether there are any methods that protest
if you give an argument and a block.... I have a memory that there
are one or two, but I'm not sure what they are.


David

--
David A. Black
(E-Mail Removed)



 
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
POD and assignment operator and test operator Hicham Mouline C++ 2 09-01-2009 06:00 PM
Rindex used to find end of a string Paul.Lee.1971 Perl Misc 4 03-11-2007 03:02 PM
rindex with regexp trans. (T. Onoma) Ruby 2 12-28-2004 04:54 AM
operator*(Foo) and operator*(int) const: ISO C++ says that these are ambiguous: Alex Vinokur C++ 4 11-26-2004 11:46 PM
rindex with array of arrays STEPHEN BECKER I V Ruby 3 09-29-2004 03:43 AM



Advertisments