I am having problems understanding the concept of Array.map. I did go to Mozilla and Tutorials Point, but they provided very limited info regarding this.

This is how I am using Array.map. It is a little complex (a bit of d3.js involved; just ignore it)

var mapCell = function (row) {
    return columns.map(function(column) {
        return { column : column, value : getColumnCell(row, column) }
    })
}
//getColumnCell is a function defined in my code
//columns is array defined at the top of my code

I do not understand exactly what this code is doing. I know its returning a new array and stuff but this part is a little tricky!

if you want to go through my code: http://jsfiddle.net/ddfsb/2/

UPDATE 1

I am using console to actually understand whats happening inside the code. Looking at the answers provided, I have clearly understood the concept of array.map. Now the only part remaining is parameters rows and columns, but there is a difference between row and rows,and column and columns in the fiddle provided

var rows//completely ok
var columns//completely ok
funcion(row)//here,source of row is unknown.getColumncell function utilizes this parameter further making it more critical
function(column)//source of column is unknown..getColumncell function utilizes this parameter further making it more critical

Any help??


Solution 1:

Let's rewrite it a bit, and start working from inside out.

var mapCell = function (row) {
  return columns.map(
    function(column) {
      return { 
        column : column, 
        value : getColumnCell(row, column)
      }
    }
  )
}

The function(column) part is essentially a function that takes a column as a parameter, and returns a new object with two properties:

  • column, that is the original value of the parameter, and
  • value, that is the result of calling the getColumnCell function on the row (external variable) and column (parameter)

The columns.map() part calls the Array.map function, that takes an array and a function, and runs the function for every last item of it, and returns the results. i.e. if the input is the array [1, 2, 3, 4, 5] and the function is something like isEven, the result will be the array [false, true, false, true, false]. In your case, the input are the columns, and the output is a list of objects, each of which has a column and a value properties.

Lastly, the var mapCell = function (row) part declares that the variable mapCell will contain a function of one variable called row - and this is the same row that is used in the inner function.

In a single sentence, this line of code, declares a function that when run, will take a row and return values for all columns for that row.

Solution 2:

Understanding the map function is only part of the solution here, there is also the function mapCell. It takes one parameter row and it returns something like:

[ {
    "column": "parties",
    "value": [cell value]
}, {
    "column": "star-speak",
    "value": [cell value]
} ]

Where the cell value depends on the row and the column (parties, stars-speak etc.)

A map function applies a transformation to a value, and returns that transformed value.

A simple example:

function square(x) { return x * x; }

[ 2, 3, 4 ].map(square); // gives: [ 4, 9, 16 ]

Similarly:

[ "parties", "starspeak" ].map(function (column) {
    return {
        column: column,
        value: findTheValue(column)
    }
});

Now since that map is nested with a function that gets a row parameter. You can use it in the map function, to get:

function (row) {
    return [ "parties", "starspeak" ].map(function (column) {
        return {
            column: column,
            value: findTheValue(row, column)
        }
    });
}

And this gets pretty close to your code.

Solution 3:

map loops through your original array and calls the method for each value in the array. It collects the results of your function to create a new array with the results. You are "mapping" the array of values into a new array of mapped values. Your code is equivalent to:

var mapCell = function (row) {
    var result = [];
        for (var i = 0; i < columns.length; ++i) {
            var mappedValue = {
                column: columns[i], 
                value : getColumnCell(row, columns[i])
            };
            result.push(mappedValue);
        }
    return result;
};