We will examine what is going on with this snippet of code? But first, what is the goal. The files variable is an array of objects. Each object has two fields: ‘name’, and ‘fullpath’. We want to return a dictionary with ‘name’ as the key, and the ‘fullpath’ as the value. We will look at this snippet of code piecemeal.
const fileMap = Object.assign({}, ...files.map(x=>({[x.name] : x.fullpath})));
Spread Syntax
The JS spread syntax allows iterable expressions, such as an array, to be expanded into an argument list during a function call. A simplified example is shown below.
const A = [1, 3, 5];
function sum(a, b, c){
return a + b + c;
}
console.log(sum(...A));
> 9
In the case of the Object.assign
function the first parameter to the object to write to, all remaining arguments are source objects. Using the spread syntax on the map function (which returns an array of objects) passes each object into ‘assign’ treating them each as individual sources.
Array.prototype.map
The map function of Array, accepts a callback function and return a new array. It fills each element of the array by passing the source value into the callback function. You can achieve the same thing by iterating through the array.
const A = [1, 1, 3, 5, 8];
const B = [];
for (let i = 0; i < A.length; i++){
B[i] = A[i] + i;
}
Equivalent operation using map:
const A = [1, 1, 3, 5, 8];
const B = A.map((x, i)=>x + i);
Lambda Functions
The snippet x=>({[x.name] : x.fullpath})
seems a little odd at first. Why are there parentheses around the curly braces. To understand this we need to look at the two ways JS allows lambda functions.
Implicit return statement:
x => {return x + 1}
Implied return statement:
x => x + 1
An implicit return statement has curly braces, while the implied does not. Because the object constructor uses the same braces as the function body, if you were to do this: x => {"name" : "apple"}
JS would think you are trying to do an implicit-return lambda function. So we need to encapsulate the object declaration with parentheses to turn that statement into an implied-return lambda function: x => ({"name" : "apple"})
.
ES2016 Computed Property Name Shorthand
The second oddity of the statement x=>({[x.name] : x.fullpath})
, is why is [x.name]
in square brackets. This was introduced in ES1015 as shorthand to tell JS to use the value in the variable and not to treat it as a key value. This is a bit more obvious if we look at it outside of the context of a lambda function.
Given an object with two fields, you want to use one of the fields for the key of a new object. The vanilla JS way of things:
const key = "name";
const obj2 = {};
obj2[key] = "apple";
console.log(obj2);
> { name: 'apple' }
The shorthand way of doing this, which fits nicely into a compact lambda function, is as follows:
const key = "name";
const obj2 = {[key] : "apple"};