Apply a callback to an array

From Rosetta Code
Revision as of 07:27, 24 January 2007 by 75.132.127.218 (talk) (added php example from php.net)

link title

Task
Apply a callback to an array
You are encouraged to solve this task according to the task description, using any language you may know.

Create a generic mapping function that applies a callback to elements in a list:

C#

Platform: .NET Language Version: 2.0+

using System; 

static class Program
{
  // Purpose: Apply a callback (or anonymous method) to an Array
  // Output: Prints the squares of an int array to the console.
  // Compiler: Visual Studio 2005
  // Framework: .net 2
   
  [STAThread]
  public static void Main() 
  {
    int[] intArray = { 1, 2, 3, 4, 5 };

    // Using a callback,
    Console.WriteLine("Printing squares using a callback:");
    Array.ForEach<int>(intArray, PrintSquare);

    // or using an anonymous method:
    Console.WriteLine("Printing squares using an anonymous method:");
    Array.ForEach<int>
    (
      intArray,
      delegate(int value) 
      {
        Console.WriteLine(value * value);    
      });
  }

  public static void PrintSquare(int value) 
  { 
    Console.WriteLine(value * value);
  }
}

C++

Compiler: GNU Compiler Collection 4.1.1

Using c-style array

#include <iostream> //cout for printing
#include <algorithm> //for_each defined here
//create the function (print the square)
void print_square(int i) {
  std::cout << i*i << " ";
}
int main() {
  //create the array
  int ary[]={1,2,3,4,5};
  //stl for_each
  std::for_each(ary,ary+5,print_square);
  return 0;
}
//prints 1 4 9 16 25

Using std::vector

#include <iostream> //cout for printing
#include <algorithm> //for_each defined here
#include <vector> //stl vector class
//create the function (print the square)
void print_square(int i) {
  std::cout << i*i << " ";
}
int main() {
  //create the array
  std::vector<int> ary;
  ary.push_back(1);
  ary.push_back(2);
  ary.push_back(3);
  ary.push_back(4);
  ary.push_back(5);
  //stl for_each
  std::for_each(ary.begin(),ary.end(),print_square);
  return 0;
}
//prints 1 4 9 16 25

More tricky with binary function

#include <iostream> //cout for printing
#include <algorithm> //for_each defined here
#include <vector> //stl vector class
#include <functional> //bind and ptr_fun
//create a binary function (print any two arguments together)
template<class type1,class type2>
void print_juxtaposed(type1 x, type2 y) {
  std::cout << x << y;
}
int main() {
  //create the array
  std::vector<int> ary;
  ary.push_back(1);
  ary.push_back(2);
  ary.push_back(3);
  ary.push_back(4);
  ary.push_back(5);
  //stl for_each, using binder and adaptable unary function
  std::for_each(ary.begin(),ary.end(),std::bind2nd(std::ptr_fun(print_juxtaposed<int,std::string>),"x "));
  return 0;
}
//prints 1x 2x 3x 4x 5x

Using Boost.Lambda

 using namespace std;
 using namespace boost::lambda;
 vector<int> ary(10);
 int i = 0;
 for_each(ary.begin(), ary.end(), _1 = ++var(i)); // init array
 transform(ary.begin(), ary.end(), ostream_iterator<int>(cout, " "), _1 * _1); // square and output

FP

Interpreter : "fp"

 {square * . [id, id]}
 & square: <1,2,3,4,5>

Haskell

Interpreter : GHCi

Compiler : GHC

 let square x = x*x
 let values = [1..10]
 map square values

Using list comprehension to generate a list of the squared values

 [square x | x <- values]

Using function composition to create a function that will print the squares of a list

 let printSquares = putStr.unlines.map (show.square)
 printSquares values

JavaScript

 function map(a, func) {
   for (var i in a)
     a[i] = func(a[i]);
 }
 var a = [1, 2, 3, 4, 5];
 map(a, function(v) { return v * v; });
 
 // JavaScript with BeyondJS
 var a = (1).to(10).collect(Math.pow.curry(undefined,2));

OCaml

This function is part of the standard library:

 Array.map

Usage example:

 let square x = x * x;;
 let values = Array.init 10 ((+) 1);;
 Array.map square values;;

Perl

 #create array                                                                                                                    
 my @a = (1,2,3,4,5);    
                                                                                                        
 #create callback function                                                                                                        
 sub mycallback {                                                                                                                 
   return 2 * shift;                                                                                                              
 }         
                                                                                                                      
 # use array indexing                                                                                                             
 my $i;                                                                                                                           
 for ($i=0;$i<scalar(@a);$i++) {                                                                                                  
   print "mycallback($a[$i]) = " , mycallback($a[$i]) , "\n";                                                                     
 }    
                                                                                                                           
 # using foreach                                                                                                                  
 foreach my $x (@a) {                                                                                                             
   print "mycallback($x) = " , mycallback($x) , "\n";                                                                             
 }    
                                                                                                                           
 # using map  (useful for transforming the array )                                                                               
 my @b = map mycallback($_),  @a;                  # @b is now (2,4,6,8,10)                                                                                                         
                                                        
 # and the same using an anonymous function
 my @c = map { $_ * 2 } @a;                        # @c is now (2,4,6,8,10)
 # use a callback stored in a variable                                                                                            
 my $func = \&mycallback;                                                                                                         
 my @d = map &{$func}($_),  @a;                    # @d is now (2,4,6,8,10)

PHP

 function cube($n)
 {
    return($n * $n * $n);
 }
 
 $a = array(1, 2, 3, 4, 5);
 $b = array_map("cube", $a);
 print_r($b);

PL/SQL

Interpreter : Oracle compiler

 set serveroutput on
 declare
 	type myarray is table of number index by binary_integer;
 	x myarray;
 	i pls_integer;
 begin
 	-- populate array
 	for i in 1..5 loop
 		x(i) := i;
 	end loop;
 	i :=0;
 
 	-- square array
 	loop
 		i := i + 1;
 		begin
 			x(i) := x(i)*x(i);
 			dbms_output.put_line(x(i));
 		exception 
 			when no_data_found then exit;
 		end;
 	end loop;
 
 end;
 /

Python

 def square(n):
   return n * n
 
 numbers = [1, 3, 5, 7]
 squares1 = [square(n) for n in numbers] # list comprehension
 squares2 = map(square, numbers) # discouraged nowadays
 squares3 = [n * n for n in numbers] # best - doesn't need a function, anonymous or otherwise

Ruby

 # You could use a traditional "for i in arr" approach like below:
 for i in [1,2,3,4,5] do
    puts i**2
 end
 # Or you could  the more preferred ruby way of an iterator (which is borrowed from SmallTalk)
 [1,2,3,4,5].each{ |i| puts i**2 }  
 # To create a new array of each value squared
 [1,2,3,4,5].map{ |i| i**2 }

Scheme

 (define (square n) (* n n))
 (define x '(1 2 3 4 5))
 (map square x)

Smalltalk

 | anArray |
 anArray = #( 1 2 3 4 5 )
 anArray do: [ :x | Transcript nextPut: x * x ]