Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
Perl: the Markov chain saw
 
PerlMonks  

Shortest -return index of element in array- sub

by leons (Pilgrim)
on Mar 21, 2001 at 15:55 UTC ( #66003=CUFP: print w/ replies, xml ) Need Help??

Hi monks,

My friend and colleague ChOas and I were having a little contest
here. We dared each other to write the shortest sub, returning the
index-number of the supplied element in an array
We came up with the following ...
#!/usr/bin/perl -w sub indexArray($@) { my $s=shift; $_ eq $s && return @_ while $_=pop; -1; } my @array=('john','paul','ringo','george'); print indexArray('john',@array) ."\n"; # Returns 0 print indexArray('ringo',@array) ."\n"; # Returns 2 print indexArray('mick',@array) ."\n"; # Returns -1

Is anyone bored enough to participate in this silly contest?
Anything, shorter, funnier, more obfuscated ... will do and
is welcome ;-)

If you do not want to participate because you think this is too
silly and a waste of your time, then please don't, cause you're
right ! ;-)

Bye, Leon

Comment on Shortest -return index of element in array- sub
Download Code
Re: Shortest -return index of element in array- sub
by jmcnamara (Monsignor) on Mar 21, 2001 at 18:03 UTC

    Not really shorter just an alternative. This is in golf mode, therefore no -w or strict:
    #!/usr/bin/perl sub indexArray { $i = -1; undef %h; map {$h{$_} = $i++} @_; $h{$_[0]} } my @array=('john','paul','ringo','george'); print indexArray('john', @array) ."\n"; # Returns 0 print indexArray('ringo',@array) ."\n"; # Returns 2 print indexArray('mick', @array) ."\n"; # Returns -1

    John.
    --

Re: Shortest -return index of element in array- sub
by ChOas (Curate) on Mar 21, 2001 at 18:37 UTC
    I think I forgot to show Leon this one ;))
    works with strict, and -w
    sub indexArray { 1 while $_[0] ne pop; @_-1; }

    Side node to Arhuman (see below): Respect goes out to you man! ;))

    GreetZ!,
      ChOas

    print "profeth still\n" if /bird|devil/;
      sub indexArray(@) { 1 while $_[0] ne pop; $#_; }
      Saves One char...
      Could be applied to some of the other solutions (jmcnamara) too...


      "Trying to be a SMART lamer" (thanx to Merlyn ;-)
Re: Shortest -return index of element in array- sub
by Tyke (Pilgrim) on Mar 21, 2001 at 18:39 UTC
    How about
    sub indexArray{for(1..@_){$_[0]eq$_[$_]&&return$_-1}-1} my @array=('john','paul','ringo','george'); print indexArray('john',@array) ."\n"; # Returns 0 print indexArray('ringo',@array) ."\n"; # Returns 2 print indexArray('mick',@array) ."\n"; # Returns -1
    retaining jmcnamara comments about golf
      If the contest is for an index and not the reverse index, then the above solution is correct. But the offerings that use pop will find the last match in the array rather than the first.
Re: Shortest -return index of element in array- sub
by jmcnamara (Monsignor) on Mar 21, 2001 at 19:00 UTC

    Or maybe this:
    sub indexArray{ while (@_) { return @_-1 if $_[0] eq pop } }

    John.
    --

    Update: Just saw ChOas' post.
      Darn. This is the route I went, too.
      Just a slight bit of difference.
      I really need to read all the posts before taking a challenge mentioned in the first one. ;-)

      sub indexArray2 { while(@_){$_[0] eq pop && return @_-1} }
      Chris
        Now that I've taken a closer look, this is the shortest iterative version I could find (and also the shortest I could make it and have it run under strictures and warnings, although those aren't really prerequisites in golf):
        sub indexArray3{ 1while$_[0]ne pop;$#_ }
        I'd say that's pretty obfuscated, too. It can be done in a couple fewer characters recursively, if you use a one-character subroutine name and eliminate any unnecessary whitespace. I'd like to know hoe to do it in fewer iteratively, but I just can't figure anything out. Please point it out to me if there's a way.

        Chris Stith

Re: Shortest -return index of element in array- sub
by lindex (Friar) on Mar 24, 2001 at 00:27 UTC
    this works:
    #!perl use strict; sub iA{join('',map{$_ if($_[0]eq$_[$_])}(1..$#_))-1} my(@array) = qw(foo bar crap stuff); print "$_: ".iA($_,@array),"\n" for(qw(foo dolsman crap));
    just my two cents :)



    lindex
    /****************************/ jason@gost.net, wh@ckz.org http://jason.gost.net /*****************************/
Re: Shortest -return index of element in array- sub
by MeowChow (Vicar) on Mar 24, 2001 at 12:02 UTC
    sub i { pop ne $_[0] ? &i : $#_ }
    Ahhh, recursion...
Re: Shortest -return index of element in array- sub
by duelafn (Priest) on Mar 24, 2001 at 15:25 UTC
    What if we want to find all of the values? The best I could do was this,
    sub find { 1 while $_[0]ne pop; $#_+1?(&a(@_),$#_):(); } my @array=('john','paul','ringo','george', 'ringo'); print &find('john',@array),"\n"; # Returns 0 print &find('ringo',@array),"\n"; # Returns 24 print &find('mick',@array),"\n"; # Returns undef
    Good Day,
        Dean
      sub i { pop eq $_[0] ? @_-1 : (), $#_ ? &i : () }
      Ahhhh, more recursion...

      ps. This is why I used @_-1 instead of $#_

      sub aindex { grep$_[$_+1]eq$_[0],0..@_-2 }
map in an avoid context
by jmcnamara (Monsignor) on Apr 09, 2001 at 15:11 UTC

    This takes my original map idea to its natural(?) conclusion. 23 chars:
    sub array_index { @_{@_}=-1..@_; $_{$_[0]} }


    John.
    --


Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://66003]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (9)
As of 2014-04-24 00:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (557 votes), past polls