This articlerelies largely or entirely on asingle source. Relevant discussion may be found on thetalk page. Please helpimprove this article byintroducing citations to additional sources. Find sources: "Map" higher-order function – news ·newspapers ·books ·scholar ·JSTOR(November 2012) |
In manyprogramming languages,map is ahigher-order function that applies agiven function to each element of acollection, e.g. alist orset, returning the results in a collection of the same type. It is often calledapply-to-all when considered infunctional form.
The concept of a map is not limited to lists: it works for sequentialcontainers, tree-like containers, or even abstract containers such asfutures and promises.
Suppose there is a list of integers[1, 2, 3, 4, 5] . To calculate thesquare of each integer, one would first define a function tosquare a single number (shown here inHaskell):
squarex=x*x
Afterwards, call:
>>>mapsquare[1,2,3,4,5]
which yields[1, 4, 9, 16, 25], demonstrating thatmap has gone through the entire list and applied the functionsquare to each element.
Below, is a view of each step of the mapping process for a list of integersX = [0, 5, 8, 3, 2, 1] mapping into a new listX' according to the function :

Themap is provided as part of the Haskell's base prelude (i.e. "standard library") and is implemented as:
map::(a->b)->[a]->[b]map_[]=[]mapf(x:xs)=fx:mapfxs
In Haskell, thepolymorphic functionmap::(a->b)->[a]->[b] is generalized to apolytypic functionfmap::Functorf=>(a->b)->fa->fb, which applies to any type belonging theFunctortype class.
Thetype constructor of lists[] can be defined as an instance of theFunctor type class using themap function from the previous example:
instanceFunctor[]wherefmap=map
Other examples ofFunctor instances include trees:
-- a simple binary treedataTreea=Leafa|Fork(Treea)(Treea)instanceFunctorTreewherefmapf(Leafx)=Leaf(fx)fmapf(Forklr)=Fork(fmapfl)(fmapfr)
Mapping over a tree yields:
>>>fmapsquare(Fork(Fork(Leaf1)(Leaf2))(Fork(Leaf3)(Leaf4)))Fork(Fork(Leaf1)(Leaf4))(Fork(Leaf9)(Leaf16))
For every instance of theFunctor type class,fmap iscontractually obliged to obey the functor laws:
fmapid≡id-- identity lawfmap(f.g)≡fmapf.fmapg-- composition law
where. denotesfunction composition in Haskell.
Among other uses, this allows defining element-wise operations for various kinds ofcollections.
Incategory theory, afunctor consists of two maps: one that sends each objectA of the category to another objectF A, and one that sends each morphism to another morphism, which acts as ahomomorphism on categories (i.e. it respects the category axioms). Interpreting the universe of data types as a categoryType, with morphisms being functions, then a type constructorF that is a member of theFunctor type class is the object part of such a functor, andfmap::(a->b)->Fa->Fb is the morphism part. The functor laws described above are precisely the category-theoretic functor axioms for this functor.
Functors can also be objects in categories, with "morphisms" callednatural transformations. Given two functors, a natural transformation consists of a collection of morphisms, one for each objectA of the categoryD, which are 'natural' in the sense that they act as a 'conversion' between the two functors, taking no account of the objects that the functors are applied to. Natural transformations correspond to functions of the formeta::Fa->Ga, wherea is a universally quantified type variable –eta knows nothing about the type which inhabitsa. The naturality axiom of such functions is automatically satisfied because it is a so-called free theorem, depending on the fact that it isparametrically polymorphic.[1] For example,reverse::Lista->Lista, which reverses a list, is a natural transformation, as isflattenInorder::Treea->Lista, which flattens a tree from left to right, and evensortBy::(a->a->Bool)->Lista->Lista, which sorts a list based on a provided comparison function.
The mathematical basis of maps allow for a number ofoptimizations. The composition law ensures that both
(map f . map g) list andmap (f . g) listlead to the same result; that is,. However, the second form is more efficient to compute than the first form, because eachmap requires rebuilding an entire list from scratch. Therefore, compilers will attempt to transform the first form into the second; this type of optimization is known asmap fusion and is thefunctional analog ofloop fusion.[2]
Map functions can be and often are defined in terms of afold such asfoldr, which means one can do amap-fold fusion:foldr f z . map g is equivalent tofoldr (f . g) z.
The implementation of map above on singly linked lists is nottail-recursive, so it may build up a lot of frames on the stack when called with a large list. Many languages alternately provide a "reverse map" function, which is equivalent to reversing a mapped list, but is tail-recursive. Here is an implementation which utilizes thefold-left function.
reverseMapf=foldl(\ysx->fx:ys)[]
Since reversing a singly linked list is also tail-recursive, reverse and reverse-map can be composed to perform normal map in a tail-recursive way, though it requires performing two passes over the list.
The map function originated infunctional programming languages.
The languageLisp introduced a map function calledmaplist[3] in 1959, with slightly different versions already appearing in 1958.[4] This is the original definition formaplist, mapping a function over successive rest lists:
maplist[x;f] = [null[x] -> NIL;T -> cons[f[x];maplist[cdr[x];f]]]
The functionmaplist is still available in newer Lisps likeCommon Lisp,[5] though functions likemapcar or the more genericmap would be preferred.
Squaring the elements of a list usingmaplist would be written inS-expression notation like this:
(maplist(lambda(l)(sqr(carl)))'(12345))
Using the functionmapcar, above example would be written like this:
(mapcar(functionsqr)'(12345))
Today mapping functions are supported (or may be defined) in manyprocedural,object-oriented, andmulti-paradigm languages as well: InC++'sStandard Library, it is calledstd::transform orstd::ranges::transform, inC# (3.0)'s LINQ library, it is provided as an extension method calledSelect. Map is also a frequently used operation in high level languages such asColdFusion Markup Language (CFML),Perl,Python, andRuby; the operation is calledmap in all four of these languages. Acollect alias formap is also provided in Ruby (fromSmalltalk).Common Lisp provides a family of map-like functions; the one corresponding to the behavior described here is calledmapcar (-car indicating access using theCAR operation). There are also languages with syntactic constructs providing the same functionality as the map function.
Map is sometimes generalized to accept dyadic (2-argument) functions that can apply a user-supplied function to corresponding elements from two lists. Some languages use special names for this, such asmap2 orzipWith. Languages using explicitvariadic functions may have versions of map with variablearity to supportvariable-arity functions. Map with 2 or more lists encounters the issue of handling when the lists are of different lengths. Various languages differ on this. Some raise an exception. Some stop after the length of the shortest list and ignore extra items on the other lists. Some continue on to the length of the longest list, and for the lists that have already ended, pass some placeholder value to the function indicating no value.
In languages which supportfirst-class functions andcurrying,map may bepartially applied tolift a function that works on only one value to an element-wise equivalent that works on an entire container; for example,map square is a Haskell function which squares each element of a list.
| Language | Map | Map 2 lists | Map n lists | Notes | Handling lists of different lengths |
|---|---|---|---|---|---|
| APL | funclist | list1funclist2 | func/list1list2list3list4 | APL's array processing abilities make operations like map implicit | length error if list lengths not equal or 1 |
| Common Lisp | (mapcarfunclist) | (mapcarfunclist1list2) | (mapcarfunclist1list2 ...) | stops after the length of the shortest list | |
| C++ | std::transform(list | std::views::transform( | std::transform(std::views::zip_transform( | std::views::zip_transform( | in header<algorithm> begin,end, andresult are iterators result is written starting atresult | |
| C# | ienum.Select(func)or The select clause | ienum1.Zip(ienum2,func) | Select is an extension methodienum is an IEnumerable Zip is introduced in .NET 4.0Similarly in all .NET languages | stops after the shortest list ends | |
| CFML | obj.map(func) | Whereobj is an array or a structure.func receives as arguments each item's value, its index or key, and a reference to the original object. | |||
| Clojure | (mapfunclist) | (mapfunclist1list2) | (mapfunclist1list2 ...) | stops after the shortest list ends | |
| D | list.map!func | zip(list1,list2).map!func | zip(list1,list2, ...).map!func | Specified to zip by StoppingPolicy: shortest, longest, or requireSameLength | |
| Erlang | lists:map(Fun,List) | lists:zipwith(Fun,List1,List2) | zipwith3 also available | Lists must be equal length | |
| Elixir | Enum.map(list,fun) | Enum.zip(list1,list2) |> Enum.map(fun) | List.zip([list1,list2, ...]) |> Enum.map(fun) | stops after the shortest list ends | |
| F# | List.mapfunclist | List.map2funclist1list2 | Functions exist for other types (Seq andArray) | Throws exception | |
| Gleam | list.map(list,func)yielder.map(yielder,func) | list.map2(list1,list2,func)yielder.map2(yielder1,yielder2,func) | drops the extra elements of the longer list | ||
| Groovy | list.collect(func) | [list1list2].transpose().collect(func) | [list1list2...].transpose().collect(func) | ||
| Haskell | mapfunclist | zipWithfunclist1list2 | zipWithnfunclist1list2 ... | n corresponds to the number of lists; predefined up tozipWith7 | stops after the shortest list ends |
| Haxe | array.map(func) | ||||
| J | funclist | list1funclist2 | func/list1,list2,list3 ,:list4 | J's array processing abilities make operations like map implicit | length error if list lengths not equal |
| Java 8+ | stream.map(func) | ||||
| JavaScript 1.6 ECMAScript 5 | array#map(func) | List1 | List1 | Array#map passes 3 arguments tofunc: the element, the index of the element, and the array. Unused arguments can be omitted. | Stops at the end ofList1, extending the shorter arrays withundefined items if needed. |
| Julia | map(func,list) | map(func,list1, list2) | map(func,list1, list2, ..., listN) | ERROR: DimensionMismatch | |
| Logtalk | map(Closure,List) | map(Closure,List1,List2) | map(Closure,List1,List2,List3, ...) (up to seven lists) | Only theClosure argument must be instantiated. | Failure |
| Mathematica | func /@list | MapThread[func, {list1,list2}] | MapThread[func, {list1,list2, ...}] | Lists must be same length | |
| Maxima | map(f,expr1, ...,exprn) | map returns an expression which leading operator is the same as that of the expressions; maplist returns a list | |||
| OCaml | List.mapfunclist | List.map2funclist1list2 | raises Invalid_argument exception | ||
| PARI/GP | apply(func,list) | — | |||
| Perl | mapblocklist | Inblock orexpr special variable$_ holds each value from list in turn. | HelperList::MoreUtils::each_array combines more than one list until the longest one is exhausted, filling the others withundef. | ||
| PHP | array_map(callable,array) | array_map(callable,array1,array2) | array_map(callable,array1,array2, ...) | The number of parameters forcallable should match the number of arrays. | extends the shorter lists withNULL items |
| Prolog | maplist(Cont,List1,List2). | maplist(Cont,List1,List2,List3). | maplist(Cont,List1,...). | List arguments are input, output or both. Subsumes also zipWith, unzip, all | Silent failure (not an error) |
| Python | map(func,list) | map(func,list1,list2) | map(func,list1,list2, ...) | Returns a list in Python 2 and aniterator in Python 3. | zip() andmap() (3.x) stops after the shortest list ends, whereasmap() (2.x) anditertools.zip_longest() (3.x) extends the shorter lists withNone items |
| Ruby | enum.collect {block} | enum1.zip(enum2) | enum1.zip(enum2, ...) | enum is an Enumeration | stops at the end of the object it is called on (the first list); if any other list is shorter, it is extended withnil items |
| Rust | list1.into_iter().map(func) | list1.into_iter().zip(list2).map(func) | theIterator::map andIterator::zip methods both take ownership of the original iterator and return a new one; theIterator::zip method internally calls theIntoIterator::into_iter method onlist2 | stops after the shorter list ends | |
| S-R | lapply(list,func) | mapply(func,list1,list2) | mapply(func,list1,list2, ...) | Shorter lists are cycled | |
| Scala | list.map(func) | (list1,list2) | (list1,list2,list3) | note: more than 3 not possible. | stops after the shorter list ends |
| Scheme (includingGuile andRacket) | (mapfunclist) | (mapfunclist1list2) | (mapfunclist1list2 ...) | lists must all have same length (SRFI-1 extends to take lists of different length) | |
| Smalltalk | aCollection collect:aBlock | aCollection1 with:aCollection2 collect:aBlock | Fails | ||
| Standard ML | mapfunclist | ListPair.mapfunc (list1,list2) | For 2-argument map,func takes its arguments in a tuple | ListPair.map stops after the shortest list ends, whereasListPair.mapEq raisesUnequalLengths exception | |
| Swift | sequence.map(func) | zip(sequence1,sequence2).map(func) | stops after the shortest list ends | ||
| XPath 3 XQuery 3 | list!blockfor-each(list,func) | for-each-pair(list1,list2,func) | Inblock the context item. holds the current value | stops after the shortest list ends |
fmap is strict.Wadler, Philip (September 1989).Theorems for free!(PDF). 4th International Symposium on Functional Programming Languages and Computer Architecture. London:Association for Computing Machinery.