From b60518d748f2d7df41fcc374c5f29bd308d8089a Mon Sep 17 00:00:00 2001 From: Zevero Date: Tue, 24 May 2016 08:36:40 +0200 Subject: [PATCH] Guarantee column order of objects. With headers. --- lib/csv-express.js | 52 +++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/lib/csv-express.js b/lib/csv-express.js index 9acd35f..872071e 100644 --- a/lib/csv-express.js +++ b/lib/csv-express.js @@ -26,7 +26,7 @@ exports.ignoreNullOrUndefined = true; */ function escape(field) { - if (exports.ignoreNullOrUndefined && field == undefined) { + if (exports.ignoreNullOrUndefined && field === undefined) { return ''; } if (exports.preventCast) { @@ -38,27 +38,6 @@ function escape(field) { return '"' + String(field).replace(/\"/g, '""') + '"'; } -/** - * Convert an object to an array of property values. - * - * Example: - * objToArray({ name: "john", id: 1 }) - * // => [ "john", 1 ] - * - * @param {Object} obj The object to convert. - * @return {Array} The array of object properties. - * @api private - */ - -function objToArray(obj) { - var result = []; - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - result.push(obj[prop]); - } - } - return result; -} /* @@ -75,23 +54,26 @@ res.csv = function(data, csvHeaders, headers, status) { this.charset = this.charset || 'utf-8'; this.header('Content-Type', 'text/csv'); - - if (csvHeaders) { - var header = []; - for (var prop in data[0]) { - if (data[0].hasOwnProperty(prop)) { - header.push(prop); - } - } - body += header + '\r\n'; - } + + var csvHeader_arr = [], csvHeader_pos = {}; //twice for better access of position data.forEach(function(item) { - if (!(item instanceof Array)) { - item = objToArray(item); + var arr = []; + if (item instanceof Array) arr = item; + else + for (var prop in item) { //former objToArray but with correct header_csv position + if (item.hasOwnProperty(prop)) { + if (csvHeader_pos[prop] === undefined) { + csvHeader_pos[prop] = csvHeader_arr.length; + csvHeader_arr.push(prop); + } + arr[csvHeader_pos[prop]] = item[prop]; + } } - body += item.map(escape).join(exports.separator) + '\r\n'; + body += arr.map(escape).join(exports.separator) + '\r\n'; }); + + if (csvHeaders && csvHeader_arr.length) body = csvHeader_arr.map(escape).join(exports.separator) + '\r\n' + body; if (this.charset !== 'utf-8') { body = iconv.encode(body, this.charset);