Skip to content

Instantly share code, notes, and snippets.

@Braunson
Created December 16, 2024 17:48
Show Gist options
  • Save Braunson/0d1d94bed61d56b1244d295572871dfd to your computer and use it in GitHub Desktop.
Save Braunson/0d1d94bed61d56b1244d295572871dfd to your computer and use it in GitHub Desktop.
console.table behavior in a custom JS function
function customConsoleTable(data) {
// Handle GroupBy results by flattening them appropriately
function flattenGroupBy(groupedData) {
if (!groupedData || typeof groupedData !== 'object') return groupedData;
// Check if this looks like a GroupBy result
const isGroupByResult = Object.values(groupedData).every(Array.isArray);
if (!isGroupByResult) return groupedData;
// Flatten the grouped structure
return Object.entries(groupedData).flatMap(([key, group]) =>
group.map(item => ({
group: key,
...item
}))
);
}
// Early return for invalid input
if (!data) return console.log(data);
// Handle GroupBy results and convert to array
const tableData = Array.isArray(data) ? data : flattenGroupBy(data);
if (!tableData?.length) return;
// Pre-allocate columns Map with width tracking
const columns = new Map();
// Single pass for columns and initial widths
for (const row of tableData) {
if (row && typeof row === 'object') {
for (const [key, value] of Object.entries(row)) {
const valueStr = String(value ?? '');
const valueLength = valueStr.length;
const currentWidth = columns.get(key) ?? key.length;
columns.set(key, Math.max(currentWidth, valueLength));
}
}
}
// Convert to array once, avoid multiple conversions
const columnData = Array.from(columns.entries());
// Prepare static templates
const horizontalBorder = (symbol) =>
`${symbol[0]}${columnData.map(([_, width]) =>
'─'.repeat(width + 2)).join(symbol[1])}${symbol[2]}`;
const topBorder = horizontalBorder(['┌', '┬', '┐']);
const middleBorder = horizontalBorder(['├', '┼', '┤']);
const bottomBorder = horizontalBorder(['└', '┴', '┘']);
// Prepare row template function
const formatRow = (getValue) =>
`│ ${columnData.map(([key, width]) =>
String(getValue(key) ?? '').padEnd(width)).join(' │ ')} │`;
// Print table
console.log(
[
topBorder,
formatRow(col => col),
middleBorder,
...tableData.map(row => formatRow(key => row[key])),
bottomBorder
].join('\n')
);
}
// Example usage with Object.groupBy result
const orders = [
{ amount: 100, status: 'pending' },
{ amount: 200, status: 'complete' },
{ amount: 300, status: 'pending' },
{ amount: 400, status: 'complete' },
];
// Simulate Object.groupBy result structure
const groupedOrders = {
pending: [
{ amount: 100, status: 'pending' },
{ amount: 300, status: 'pending' }
],
complete: [
{ amount: 200, status: 'complete' },
{ amount: 400, status: 'complete' }
]
};
console.log('Regular array input:');
customConsoleTable(orders);
console.log('\nGrouped data input:');
customConsoleTable(groupedOrders);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment