rowsToObjects and objectsToRows

Sheet data is easiest as a 2D array. Business logic is easier as objects keyed by header. These two helpers convert back and forth without dragging a dependency into a bootstrapper file.

What you'll need

  • A 2D array from getValues() (header row first), or
  • An array of plain objects plus an optional header order when writing back

rowsToObjects

Takes [[headers...], [row]...] and returns [{header: value, ...}, ...].

function rowsToObjects(rows) { if (!rows || !rows.length) return []; var headers = rows[0].map(function (h) { return String(h).trim(); }); return rows.slice(1).map(function (row) { var obj = {}; for (var i = 0; i < headers.length; i++) { obj[headers[i]] = row[i]; } return obj; }); }

objectsToRows

Takes objects and an optional header list (column order). Returns a 2D array ready for setValues, header included.

function objectsToRows(objects, headers) { if (!objects || !objects.length) return [headers || []]; headers = headers || Object.keys(objects[0]); var body = objects.map(function (obj) { return headers.map(function (key) { return obj.hasOwnProperty(key) ? obj[key] : ''; }); }); return [headers].concat(body); }

Round-trip example

function filterActiveAndWrite() { var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('People'); var values = sheet.getDataRange().getValues(); var people = rowsToObjects(values); var active = people.filter(function (p) { return p.Status === 'Active'; }); var headers = values[0]; var out = objectsToRows(active, headers); var dest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('ActivePeople'); dest.clearContents(); dest.getRange(1, 1, out.length, out[0].length).setValues(out); }

Tips:

  • Trim headers once so "Name " and "Name" don't become two different keys.
  • Pass an explicit headers array into objectsToRows when column order matters (Sheets care; Object.keys order is usually insertion order but don't gamble on it for client deliverables).
  • Blank source rows still become objects — pair with a blank-row filter snippet if you need to drop them first.

Happy Coding!

NitroGAS Chrome Extension

Want this snippet handy inside the Apps Script editor? NitroGAS gives you free themes and snippets — plus optional Co-Pilot when you want a boost (1-week, 1-month, or yearly passes — no subscription). Happy Coding!

Get the Extension