Apply a callback to an array: Difference between revisions
m (→{{header|D}}) |
|||
Line 280: | Line 280: | ||
=={{header|D}}== |
=={{header|D}}== |
||
<d>U[] map(T, U)(T[] array, U delegate(T) dg) { |
|||
⚫ | |||
{ |
|||
⚫ | |||
foreach (index, element; array) |
foreach (index, element; array) |
||
result[index] = dg(element); |
result[index] = dg(element); |
||
return result; |
return result; |
||
} |
|||
void main() { |
|||
⚫ | |||
{ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
[1, 2, 3, 4, 5].map( |
|||
}</d> |
|||
⚫ | |||
) |
|||
⚫ | |||
} |
|||
=={{header|E}}== |
=={{header|E}}== |
Revision as of 23:07, 28 April 2008
You are encouraged to solve this task according to the task description, using any language you may know.
In this task, the goal is to take a combined set of elements and apply a function to each element.
Ada
<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
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#
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); } }
This version uses the C# 3 lambda notation.
int[] intArray = { 1, 2, 3, 4, 5 }; Array.ForEach(intArray, i => Console.WriteLine(i * i));
C++
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
#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
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*)
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>
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
In ISO Fortran 95 or later, use elemental functions:
ELEMENTAL FUNCTION CUBE( X ) IMPLICIT NONE REAL :: CUBE REAL, INTENT(IN) :: X CUBE = X * X * X END FUNCTION CUBE
PROGRAM EXAMPLE IMPLICIT NONE INTEGER :: I, J REAL, DIMENSION(3,4) :: B, & A = RESHAPE( (/ ((0.1 * 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 EXAMPLE
ANSI FORTRAN 77 (with MIL-STD-1753 structured DO) Example:
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
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
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
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; });
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)];
Functional.map('x*x*x', [1,2,3,4,5])
Logo
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.
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
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
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
To print squares of integers in the range from 0 to 9, type:
print " ".join(str(n * n) for n in range(10))
Or:
print " ".join(map(str, map(square, range(10))))
Result:
0 1 4 9 16 25 36 49 64 81
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 var [array names dat] { myfunc $dat($var) }
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
Visual Basic .NET
Platform: .NET
Dim intArray As Integer() = {1, 2, 3, 4, 5} Array.ForEach(intArray, Function(i) Console.WriteLine(i * i))