Search a list: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|J}}: correction)
(Adding Haskell)
Line 82: Line 82:
4 Bush
4 Bush
</pre>
</pre>

=={{header|Haskell}}==
Libraries and data:
import Data.List
haystack=["Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo"]
needles = ["Washington","Bush"]
I use 'lambda' notation for readability.
:Find 'just' an index:
*Main> map (\x -> (x,findIndex (==x) haystack)) needles
[("Washington",Nothing),("Bush",Just 3)]
Want to know if there are there more Bushes hiding in the haystack?
*Main> map (\x -> (x,findIndices (==x) haystack)) needles
[("Washington",[]),("Bush",[3,7])]
To be complete. Here is the 'point free' version of the task:
import Control.Monad
import Control.Arrow

*Main> map (ap (,) (flip findIndex haystack . (==))) needles
[("Washington",Nothing),("Bush",Just 3)]


=={{header|J}}==
=={{header|J}}==

Revision as of 07:36, 29 September 2008

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

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.

Ada

<ada> with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Ada.Text_IO; use Ada.Text_IO;

procedure Test_List_Index is

  Not_In : exception;
  
  type List is array (Positive range <>) of Unbounded_String;
  
  function Index (Haystack : List; Needle : String) return Positive is
  begin
     for Index in Haystack'Range loop
        if Haystack (Index) = Needle then
           return Index;
        end if;
     end loop;
     raise Not_In;
  end Index;
     -- Functions to create lists
  function "+" (X, Y : String) return List is
  begin
     return (1 => To_Unbounded_String (X), 2 => To_Unbounded_String (Y));
  end "+";
  
  function "+" (X : List; Y : String) return List is
  begin
     return X & (1 => To_Unbounded_String (Y));
  end "+";
  
  Haystack : List := "Zig"+"Zag"+"Ronald"+"Bush"+"Krusty"+"Wally"+"Charlie"+"Bush"+"Bozo";
  procedure Check (Needle : String) is
  begin
     Put (Needle);
     Put_Line ("at" & Positive'Image (Index (Haystack, Needle)));
  exception
     when Not_In => Put_Line (" is not in");
  end Check;

begin

  Check ("Washington");
  Check ("Bush");

end Test_List_Index; </ada> Sample output:

Washington is not in
Bushat 4

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

Haskell

Libraries and data:

import Data.List

haystack=["Zig","Zag","Ronald","Bush","Krusty","Wally","Charlie","Bush","Bozo"]
needles = ["Washington","Bush"]

I use 'lambda' notation for readability.

Find 'just' an index:
*Main> map (\x -> (x,findIndex (==x) haystack)) needles
[("Washington",Nothing),("Bush",Just 3)]

Want to know if there are there more Bushes hiding in the haystack?

*Main> map (\x -> (x,findIndices (==x) haystack)) needles
[("Washington",[]),("Bush",[3,7])]

To be complete. Here is the 'point free' version of the task:

import Control.Monad
import Control.Arrow
*Main> map (ap (,) (flip findIndex haystack . (==))) needles
[("Washington",Nothing),("Bush",Just 3)] 

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 
9 3

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

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

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

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, an index past the end of the list). 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