Find the index of a string (needle) in an array of strings (haystack), or else raise an exception if the needle is missing. If there is more then one occurrence then return smallest i such that haystack[i] = needle.

Task
Search a list
You are encouraged to solve this task according to the task description, using any language you may know.

ALGOL 68

FORMAT hay stack := $c("Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo")$;

[]STRING needles = ("Washington","Bush");

FILE needle exception; STRING ref needle;
associate(needle exception, ref needle);

PROC index = (FORMAT haystack, REF STRING needle)INT:(
  INT out;
  ref needle := needle;
  getf(needle exception,(haystack, out));
  out
);

FOR i TO UPB needles DO
  STRING needle := needles[i];
  on value error(needle exception, (REF FILE f)BOOL: value error);
    printf(($d" "gl$,index(hay stack, needle), needle));
    end on value error;
  value error:
    printf(($g" "gl$,needle, "is not in haystack"));
  end on value error: reset(needle exception)
OD

Output:

Washington is not in haystack
4 Bush

J

J has a general and optimized lookup function, i.. For example:

   H =: ;:'Zig Zag Ronald. Bush Krusty Wally Charlie Bush Bozo'
  NB.  Haystack
   N =: ;:'Washington Bush'
  NB.   Needles
   
   H i. N 
_1 3

Note that the arguments to i. can be anything (ie either or both may be scalars, lists, multidimensional arrays, etc).

To produce output similar to the other examples, one might write:

   H ;:^:_1@(] (>@{.@[ |."_1 (,. >@{:)) i. ([;{) ' is not in haystack' ;~  ":&.>@i.@[)~ N

To elaborate a bit: Array-oriented languages (like J) consume the input and produce the output in toto.

That is, all the results are produced simultaneously; consequently, throwing an exception for any part of the input would prohibit producing any output at all.

And while it is both possible and simple to treat the input item by item, this is significantly slower and loses the great advantage of array processing.

Therefore these languages generally produce a special, but conforming, output for "bad" inputs (in this case, -1). Then the functions which consume these outputs may be left untouched (as the special outputs are already in their domain) or may be extended simply.

In this case, there is only one function which formats and prints the results, and its treatment of "good" and "bad" outputs is identical (it cannot distinguish the two). It is simply that the outputs of previous functions have been arranged such that the results are conformable.

N.B. I wrote this up from my phone, without access to J (the fact that J is terse and high-level enough to make this possible is another of its advantages), so I would appreciate if someone with access to and knowledge of J check for and correct any errors.

Java

for Lists, they have an indexOf() method: <java>import java.util.List; import java.util.Arrays;

List<String> haystack = Arrays.asList("Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo");

for (String needle : new String[]{"Washington","Bush"}) {

   int index = haystack.indexOf(needle);
   if (index < 0)
       System.out.println(needle + " is not in haystack");
   else
       System.out.println(index + " " + needle);

}</java>

for arrays, you have to do it manually: <java>String[] haystack = {"Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo"};

OUTERLOOP: for (String needle : new String[]{"Washington","Bush"}) {

   for (int i = 0; i < haystack.length; i++)
       if (needle.equals(haystack[i])) {
           System.out.println(i + " " + needle);
           continue OUTERLOOP;
       }
   System.out.println(needle + " is not in haystack");

}</java>

Output:

Washington is not in haystack
3 Bush

Python

<python> haystack=["Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo"]

for needle in ("Washington","Bush"):

 try:
   print haystack.index(needle), needle
 except ValueError, value_error:
   print needle,"is not in haystack"

</python> Output:

Washington is not in haystack
3 Bush