JavaScript Arrays: Map
Map: One-for-one Changes Sometimes you want to modify data to return part of it or perform a consistent operation. This is mapping. Method Returns One-for-one Runs for All .map((value, index, array) => *) Array Yes Yes Whenever you need an output for every input, map is usually the place to start. This takes a mapper function that operates on each record. The value returned by the mapper appears in the new array at the same position as the original value. From for to .map() .map() neatly matches a the basic for loop. We need to convert these entries to capital letters: const data = ['a', 'b', 'c', 'd']; // Older Imperative way - for loop function mapToUpper(data) { const newData = new Array(data.length); for (let i = 0; i data .map(value => value.toUpperCase()); Some of the variations like const newData = new Array(data.length) versus const newData = [] aren't required by different loop types, but represent some historical variations in coding style. Use Cases Data Transformation Common uses of .map() include getting a value out of an object or performing a consistent change or transformation to data. Often we might need one piece of information out of each larger record. Map is there for us. const data = [{ name: 'Alec Berg', roles: ['Creator', 'Executive Producer'], }, { name: 'Bill Hader', roles: ['Creator', 'Executive Producer', 'Actor', 'Director'], }]; // We just need names data.map((entry) => entry.name); // [ 'Alec Berg', 'Bill Hader' ] If we needed to offer an employee discount on an order, map can do that! const cart = [{ itemId: 12345, name: 'shoes', price: 70.00, },{ itemId: 54321, name: 'shirt', price: 15.25, }]; // Apply a discount const applyDiscount = (discountPercent, order) => { // First, get the "remaining" amount. // If the discount is 10%, the multiplier is 0.9 const multiplier = 1 - (discountPercent / 100); // Create a new entry for each item with the discounted price. // We will include the old price for reference. return order.map((item) => ({ ...item, price: item.price * multiplier, originalPrice: item.price, })); }; For this one I didn't put the output. If you want to try it yourself I suggest pasting this into a browser console or a tool like RunJS, which I use to write and test these examples. Increment This is a special version of data transformation. We start with "no information", but the act of having an array provides us with an index for each entry, and we can transform the index – which starts at zero – into counting numbers just by adding one. We don't need to use the value, the first argument provided to the mapper function, but we have to provide a name for it so we can get to the second argument. The underscore character is a valid variable name which is often used to represent a value we don't need, like in this case. const getCountingNumbers = (upTo) => new Array(upTo) // New arrays are "sparse" and need values to map .fill('') // The second argument is the array index. .map((_, index) => index + 1); getCountingNumbers(5); // [ 1, 2, 3, 4, 5 ] While this is an example of .map(), a newer function can also perform this: Array.from(). const getCountingNumbers = (upTo) => Array.from( // "fake" an array-like by providing an object with length { length: upTo }, // Use the same mapper function as .map(). (_, index) => index + 1 ); It might seem odd to talk about another method while we're working in .map(), but under the hood Array.from() calls .map(), at least for the example above. Summary Hopefully this provides a little insight into using .map(). Data transformation is at the core of so many tools and industries, so .map() is a critical part of many projects. If you have any questions or comments about .map(), I would be happy to discuss!
Map: One-for-one Changes
Sometimes you want to modify data to return part of it or perform a consistent operation. This is mapping.
Method | Returns | One-for-one | Runs for All |
---|---|---|---|
.map((value, index, array) => *) |
Array |
Yes | Yes |
Whenever you need an output for every input, map is usually the place to start. This takes a mapper function that operates on each record. The value returned by the mapper appears in the new array at the same position as the original value.
From for
to .map()
.map()
neatly matches a the basic for
loop.
We need to convert these entries to capital letters:
const data = ['a', 'b', 'c', 'd'];
// Older Imperative way - for loop
function mapToUpper(data) {
const newData = new Array(data.length);
for (let i = 0; i < data.length; i += 1) {
newData[i] = data[i].toUpperCase());
}
return newData;
}
// Newer Imperative way - for..of loop
function mapToUpper(data) {
const newData = [];
for (let value of data) {
newData.push(value.toUpperCase());
}
return newData;
}
// New Declarative way - .map()
const mapToUpper = (data) => data
.map(value => value.toUpperCase());
Some of the variations like const newData = new Array(data.length)
versus const newData = []
aren't required by different loop types, but represent some historical variations in coding style.
Use Cases
Data Transformation
Common uses of .map()
include getting a value out of an object or performing a consistent change or transformation to data.
Often we might need one piece of information out of each larger record. Map is there for us.
const data = [{
name: 'Alec Berg',
roles: ['Creator', 'Executive Producer'],
}, {
name: 'Bill Hader',
roles: ['Creator', 'Executive Producer', 'Actor', 'Director'],
}];
// We just need names
data.map((entry) => entry.name);
// [ 'Alec Berg', 'Bill Hader' ]
If we needed to offer an employee discount on an order, map can do that!
const cart = [{
itemId: 12345,
name: 'shoes',
price: 70.00,
},{
itemId: 54321,
name: 'shirt',
price: 15.25,
}];
// Apply a discount
const applyDiscount = (discountPercent, order) => {
// First, get the "remaining" amount.
// If the discount is 10%, the multiplier is 0.9
const multiplier = 1 - (discountPercent / 100);
// Create a new entry for each item with the discounted price.
// We will include the old price for reference.
return order.map((item) => ({
...item,
price: item.price * multiplier,
originalPrice: item.price,
}));
};
For this one I didn't put the output. If you want to try it yourself I suggest pasting this into a browser console or a tool like RunJS, which I use to write and test these examples.
Increment
This is a special version of data transformation. We start with "no information", but the act of having an array provides us with an index for each entry, and we can transform the index – which starts at zero – into counting numbers just by adding one.
We don't need to use the value
, the first argument provided to the mapper function, but we have to provide a name for it so we can get to the second argument. The underscore character is a valid variable name which is often used to represent a value we don't need, like in this case.
const getCountingNumbers = (upTo) => new Array(upTo)
// New arrays are "sparse" and need values to map
.fill('')
// The second argument is the array index.
.map((_, index) => index + 1);
getCountingNumbers(5);
// [ 1, 2, 3, 4, 5 ]
While this is an example of .map()
, a newer function can also perform this: Array.from()
.
const getCountingNumbers = (upTo) => Array.from(
// "fake" an array-like by providing an object with length
{ length: upTo },
// Use the same mapper function as .map().
(_, index) => index + 1
);
It might seem odd to talk about another method while we're working in .map()
, but under the hood Array.from()
calls .map()
, at least for the example above.
Summary
Hopefully this provides a little insight into using .map()
. Data transformation is at the core of so many tools and industries, so .map()
is a critical part of many projects.
If you have any questions or comments about .map()
, I would be happy to discuss!
What's Your Reaction?