An interesting use of the reduce function to convert tab-delimited data into JSON I am learning functional programming in JavaScript. This is some code from a video tutorial by funfunfunction. I am particularly concerned about the way the existence of the customer key is checked in the customers object.

Is it weird to do it this way? Is there any other way? Also, if you switch the order of the OR statement operands, the object is overwritten. Does order matter in an OR statement?

The function:

var fs = require('fs')

var output = fs.readFileSync('data2.txt', 'utf8')
  .trim()
  .split('\r\n')
  .map(function(line) {
    return line.split('\t')
  })
  .reduce(function(customers, line) {
    customers[line[0]] = customers[line[0]] || []
    customers[line[0]].push({
      item: line[1],
      quantity: line[2],
      price: line[3],
    })
    return customers
  }, {})

console.log('output', JSON.stringify(output, null, 2));


The data:




Marry Poppins red bicycle 80  2
Marry Poppins glass vase  20  8
Abe Lincoln   gold ring   1   100
Marry Poppins umbrella    5   50
Steve Rogers  video camera    1   100
Abe Lincoln   president chair 1   1000
Marry Poppins blue dress  2   200
So for your first question, that is not a weird way to check the existence, and it is used quite frequently to check whether certain variables/properties are set (such as checking browser compatibility, optional arguments with defaults in functions). It typically just works as a "use this value if it exists, otherwise use this value."

You could check/set it any number of ways, like the ternary operator.

customer[line[0]] = customer[line[0]] ? customer[line[0]] : {}; 


In the same vein, you could just use an if statement to check if it is defined.

Order definitely does matter in an OR statement. In javascript (and probably most other languages) the first condition/operation is always performed, and the 2nd condition or operation is ignored unless the first condition/operation equated to a falsy value. In your example, customer[line[0]] is only assigned as an empty object if customer[line[0]] is undefined. If you reverse the order, customer[line[0]] will always be assigned to the empty object, and the 2nd half of the statement is ignored.

Javascript is the only language I've used where OR statements are normally used outside of actual control statements, so it was definitely puzzling to look at these statements at first.

Another, similar operator is the comma , operator, which is essentially the lowest in the order of operations. It just returns the last of the comma-separated statements, but all of the statements are performed.