Apply a callback to an array

Revision as of 17:44, 16 October 2008 by rosettacode>DanBron (→‎{{header|J}}: clarify)

In this task, the goal is to take a combined set of elements and apply a function to each element.

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.

Ada

Works with: GNAT version GPL 2005

<ada>with Ada.Text_Io;

with Ada.Integer_text_IO;

procedure Call_Back_Example is
   -- Purpose: Apply a callback to an array
   -- Output: Prints the squares of an integer array to the console
  
   -- Define the callback procedure
   procedure Display(Location : Positive; Value : Integer) is
   begin
      Ada.Text_Io.Put("array(");
      Ada.Integer_Text_Io.Put(Item => Location, Width => 1);
      Ada.Text_Io.Put(") = ");
      Ada.Integer_Text_Io.Put(Item => Value * Value, Width => 1);
      Ada.Text_Io.New_Line;
   end Display;
  
   -- Define an access type matching the signature of the callback procedure
   type Call_Back_Access is access procedure(L : Positive; V : Integer);
  
   -- Define an unconstrained array type
   type Value_Array is array(Positive range <>) of Integer;
  
   -- Define the procedure performing the callback
   procedure Map(Values : Value_Array; Worker : Call_Back_Access) is
   begin
      for I in Values'range loop
         Worker(I, Values(I));
      end loop;
   end Map;
  
   -- Define and initialize the actual array
   Sample : Value_Array := (5,4,3,2,1);
  
begin
   Map(Sample, Display'access);   
end Call_Back_Example;</ada>

ALGOL 68

 PROC call back proc = (INT location, INT value)VOID:
 (
   printf(($"array["g"] = "gl$, location, value))
 );

 PROC map = (REF[]INT array, PROC (INT,INT)VOID call back)VOID:
 (
   FOR i FROM LWB array TO UPB array DO
      call back(i, array[i])
   OD
 );
 
 main:
 (
   [4]INT array := ( 1, 4, 9, 16 );
   map(array, call back proc)
 )

Output:

array[         +1] =          +1
array[         +2] =          +4
array[         +3] =          +9
array[         +4] =         +16


C

Works with: gcc version 4.1.1
Works with: TCC version 0.9.23
Works with: ICC version 9.1

callback.h

 #ifndef __CALLBACK_H
 #define __CALLBACK_H
 /*
  * By declaring the function in a separate file, we allow
  * it to be used by other source files.
  *
  * It also stops ICC from complaining.
  *
  * If you don't want to use it outside of callback.c, this
  * file can be removed, provided the static keyword is prepended
  * to the definition.
  */
 void map(int* array, int len, void(*callback)(int,int));
 #endif

callback.c

 #include <stdio.h>
 #include "callback.h"
 /*
  * We don't need this function outside of this file, so
  * we declare it static.
  */
 static void callbackFunction(int location, int value)
 {
   printf("array[%d] = %d\n", location, value);
 } 
 void map(int* array, int len, void(*callback)(int,int))
 {
   int i;
   for(i = 0; i < len; i++)
   {
      callback(i, array[i]);
   }
 } 
 int main()
 {
   int array[] = { 1, 2, 3, 4 };
   map(array, 4, callbackFunction);
   return 0;
 }

Output

 array[0] = 1
 array[1] = 2
 array[2] = 3
 array[3] = 4

C#

Works with: C# version 2.0+
Works with: Visual C# version 2005
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);
  }
}


Works with: C# version 3.0+

This version uses the C# 3 lambda notation.

int[] intArray = { 1, 2, 3, 4, 5 };
Array.ForEach(intArray, i => Console.WriteLine(i * i));

C++

Works with: g++ version 4.1.1

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

std::vector

Library: STL
#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

Boost.Lambda

Library: Boost
 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

Clean

Define a function and an initial (unboxed) array.

square x = x * x

values :: {#Int}
values = {x \\ x <- [1 .. 10]}

One can easily define a map for arrays, which is overloaded and works for all kinds of arrays (lazy, strict, unboxed).

mapArray f array = {f x \\ x <-: array}

Apply the function to the initial array (using a comprehension) and print result.

Start :: {#Int}
Start = mapArray square values

Common Lisp

Imperative: print 1, 2, 3, 4 and 5:

 (map nil #'print #(1 2 3 4 5))

Functional: collect squares into new vector that is returned:

 (defun square (x) (* x x))
 (map 'vector #'square #(1 2 3 4 5))

Destructive, like the Javascript example; add 1 to every slot of vector *a*:

 (defvar *a* (vector 1 2 3))
 (map-into *a* #'1+ *a*)

Clojure

;; apply a named function, inc
(map inc [1 2 3 4])
;; apply a function
(map (fn [x] (* x x)) [1 2 3 4])
;; shortcut syntax for a function
(map #(* % %) [1 2 3 4])

D

<d>U[] map(T, U)(T[] array, U delegate(T) dg) {

   auto result = new U[array.length];

   foreach (index, element; array)
       result[index] = dg(element);

   return result;

}

void main() {

   writefln(
       [1, 2, 3, 4, 5].map( (int i) { return i+5; } )   
   );

}</d> Using std.algorithm: <d>writefln(map!("a + 5")([1, 2, 3, 4, 5]));</d>

E

def array := [1,2,3,4,5]
def square(value) { 
    return value * value
}

Example of builtin iteration:

def callback(index, value) { 
    println(`Item $index is $value.`)
}
array.iterate(callback)

There is no built-in map function yet. The following is one of the ways one could be implemented, returning a plain list (which is usually an array in implementation).

def map(func, collection) {
    def output := [].diverge()
    for item in collection {
        output.push(func(item))
    }
    return output.snapshot()
}
println(map(square, array))

Forth

This is a word that will call a given function on each cell in an array.

: map ( addr n fn -- )
   -rot cells bounds do  i @ over execute i !  cell +loop ;

Example usage:

create data 1 , 2 , 3 , 4 , 5 ,
data 5 ' 1+ map  \ adds one to each element of data

Fortran

Elemental functions.

Works with: Fortran version ISO 95 and later
module arrCallback
contains
    elemental function cube( x )
        implicit none
        real :: cube
        real, intent(in) :: x
        cube = x * x * x
    end function cube
end module arrCallback
program testAC
    use arrCallback
    implicit none
    integer :: i, j
    real, dimension(3,4) :: b, &
        a = reshape( (/ ((10 * i + j, i = 1, 3), j = 1, 4) /), (/ 3,4 /) )
     
    do i = 1, 3
        write(*,*) a(i,:)
    end do
     
    b = cube( a )  ! Applies CUBE to every member of a,
                   ! and stores each result in the equivalent element of b
    do i = 1, 3
        write(*,*) b(i,:)
    end do
end program testAC

Template:Works with ANSI

      program test
C
C--   Declare array:
      integer a(5)
C
C--   Fill it with Data
      data a /45,22,67,87,98/
C
C--   Do something with all elements (in this case: print their squares)
      do i=1,5
        print *,a(i)*a(i)
      end do
C
      end

FP

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

Groovy

Print each value in a list

[1,2,3,4].each { println it }

Create a new list containing the squares of another list

[1,2,3,4].collect { it * it }

Haskell

List

Works with: 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

Array

Works with: GHC
 import Data.Array.IArray
 let square x = x*x
 let values = array (1,10) [(i,i)|i <- [1..10]] :: Array Int Int
 amap square values

IDL

Hard to come up with an example that isn't completely contrived. IDL doesn't really distinguish between a scalar and an array; thus

 b = a^3

will yield a scalar if a is scalar or a vector if a is a vector or an n-dimensional array if a is an n-dimensional array

Io

list(1,2,3,4,5) map(squared)

J

Solution:

   "_1

Example:

   callback =:  *:
   array    =:  1 2 3 4 5
  
   callback"_1 array
1 4 9 16 25

Java

As of the current version of Java, you have to define an interface for each type of function you want to use. The next version of Java will introduce function types.

So if you want to perform an action (which doesn't return anything) on an array of int's:

<java>interface IntToVoid {

   void run(int x);

}

for (int z : myIntArray) {

   new IntToVoid() {
       public void run(int x) {
           System.out.println(x);
       }
   }.run(z);

}</java>

Or if you want to perform "map" - return an array of the results of function applications:

<java>interface IntToInt {

   int run(int x);

}

int[] result = new int[myIntArray.length]; for (int i = 0; i < myIntArray.length; i++) {

   result[i] =
       new IntToInt() {
           public int run(int x) {
               return x * x;
           }
       }.run(myIntArray[i]);

}</java>

JavaScript

Portable technique:

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; });
Library: BeyondJS

With the BeyondJS library:

var a = (1).to(10).collect(Math.pow.curry(undefined,2));

With Firefox 2.0:

function cube(num) {
  return Math.pow(num, 3);
}

var numbers = [1, 2, 3, 4, 5];

//get results of calling cube on every element
var cubes1 = numbers.map(cube);

//display each result in a separate dialog
cubes1.forEach(alert);

//array comprehension
var cubes2 = [cube(n) for each (n in numbers)];
var cubes3 = [n * n * n for each (n in numbers)];
Library: Functional
Functional.map('x*x*x', [1,2,3,4,5])

to square :x
  output :x * :x
end
show map "square [1 2 3 4 5]  ; [1 4 9 16 25]
show map [? * ?] [1 2 3 4 5]  ; [1 4 9 16 25]
foreach [1 2 3 4 5] [print square ?]  ; 1 4 9 16 25, one per line

Lua

Say we have an array:

myArray = {1, 2, 3, 4, 5}

A map function for this would be

map = function(f, data)
   local result = {}
   for k,v in ipairs(data) do
      result[k] = f(v)
   end
   return result
end

Together with our array and and a square function this yields:

myFunc = function(x) return x*x end

print(unpack( map(myFunc, myArray) ))
--> 1   4   9   16  25

If you used pairs() instead of ipairs(), this would even work on a hash table in general.

Nial

each (* [first, first] ) 1 2 3 4
=1 4 9 16

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;;

Oz

functor
import
  Application System
define 

  Print = System.showInfo

  fun{Square A}
    A*A
  end

  fun{FuncEach Func A}
    {Map A Func}
  end

  proc{ProcEach Proc A}
    {ForAll A Proc}
  end

  Arr = [1 2 3 4 5]

  {ProcEach Print {FuncEach Square Arr}}

  {ForAll {Map Arr Square} Print}           %% same

  {Application.exit 0}
end

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 an 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

Works with: Oracle
 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;
 /

Pop11

;;; Define a procedure
define proc(x);
    printf(x*x, '%p,');
enddefine;
;;; Create array
lvars ar = { 1 2 3 4 5};
;;; Apply procedure to array
appdata(ar, proc);

If one wants to create a new array consisting of transformed values then procedure mapdata may be more convenient.

Python

<python> def square(n):

   return n * n
 

numbers = [1, 3, 5, 7]

squares1 = [square(n) for n in numbers] # list comprehension

squares2a = map(square, numbers) # functional form

squares2b = map(lambda x: x*x, numbers) # functional form with `lambda`

squares3 = [n * n for n in numbers] # no need for a function,

                                           # anonymous or otherwise

isquares1 = (n * n for n in numbers) # iterator, lazy

import itertools isquares2 = itertools.imap(square, numbers) # iterator, lazy </python> To print squares of integers in the range from 0 to 9, type:

<python>print " ".join(str(n * n) for n in range(10))</python>

Or:

<python>print " ".join(map(str, map(square, range(10))))</python>

Result:

<python>0 1 4 9 16 25 36 49 64 81</python>

Raven

 # To print the squared elements
 [1 2 3 4 5] each dup * print
 # To obtain a new array
 group [1 2 3 4 5] each
   dup *
 list

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 }

Scala

 val l = List(1,2,3,4)
 l.foreach {i => println(i)}

When the argument appears only once -as here, i appears only one in println(i) - it may be shortened to

l.foreach(println(_))

Same for an array

 val a = Array(1,2,3,4)
 a.foreach {i => println(i)}
 a.foreach(println(_))   // same as previous line

Or for an externally defined function:

 def doSomething(in: int) = {println("Doing something with "+in)}
 l.foreach(doSomething)

There is also a for syntax, which is internally rewritten to call foreach. A foreach method must be defined on a

for(val i <- a) println(i)

It is also possible to apply a function on each item of an list to get a new list (same on array and most collections)

val squares = l.map{i => i * i} //squares is  List(1,4,9,16)

Or the equivalent for syntax, with the additional keyword yield, map is called instead of foreach

val squares = for (val i <- l) yield i * i

Scheme

 (define (square n) (* n n))
 (define x #(1 2 3 4 5))
 (map square (vector->list x))


A single-line variation

 (map (lambda (n) (* n n)) '(1 2 3 4 5))

For completeness, the map function (which is R5RS standard) can be coded as follows:

 (define (map f L)
   (if (null? L)
       L
       (cons (f (car L)) (map f (cdr L)))))

Smalltalk

 #( 1 2 3 4 5 ) collect: [:n | n * n].

Tcl

If I wanted to call "myfunc" on each element of dat and dat were a list:

 foreach var $dat { myfunc $var }

if dat were an array, however:

 foreach name [array names dat] { myfunc $dat($name) }

Toka

 ( array count function -- )
 {
   value| array fn |
   [ i array ] is I
   [ to fn swap to array 0 swap [ I array.get :stack fn invoke I array.put ] countedLoop ]
 } is map-array
 
 ( Build an array )
 5 cells is-array a
 10 0 a array.put
 11 1 a array.put
 12 2 a array.put
 13 3 a array.put
 14 4 a array.put
 
 ( Add 1 to each item in the array )
 a 5  [ 1 + ] map-array

V

apply squaring (dup *) to each member of collection

[1 2 3 4] [dup *] map