Matrix I/O in PHP 5.3
Inspired by the Grid Computing challenge at Code Golf, I came up with a couple of useful functions for reading and writing matrices in PHP 5.3
<?php
/**
* Returns the array of rows by columns whose values are from the given matrix.
* NOTE: white space is discarded.
*
* @param string $matrix (example)
* '
* A, B, C, D, E
* FFF, G, H, I, J
* K, L, MM, N, P
* Q, R, S, T, UUUU
* VVVVV, W, X, Y, Z
* ';
* @param array $glue
* rows => string, separator that glues rows together
* cols => string, separator that glues columns together
* @return array (example)
* array(
* array( 'A', 'B', 'C', 'D', 'E',),
* array( 'FFF', 'G', 'H', 'I', 'J',),
* array( 'K', 'L', 'MM', 'N', 'P',),
* array( 'Q', 'R', 'S', 'T', 'UUUU',),
* array('VVVVV', 'W', 'X', 'Y', 'Z',),
* );
*/
function matrixToRowsByColumns($matrix, $glue = array('rows' => "\n", 'cols' => ','))
{
$result = array_map(function($row) use ($glue)
{
return array_map('trim', explode($glue['cols'], $row));
}, explode($glue['rows'], trim($matrix)));
return $result;
}
/**
* Returns the array of rows by columns whose rows and columns are the columns
* and rows respectively of the given array of rows by columns
*
* @param array $rows (example)
* array(
* array( 'A', 'B', 'C', 'D', 'E',),
* array( 'FFF', 'G', 'H', 'I', 'J',),
* array( 'K', 'L', 'MM', 'N', 'P',),
* array( 'Q', 'R', 'S', 'T', 'UUUU',),
* array('VVVVV', 'W', 'X', 'Y', 'Z',),
* );
* @return array (example)
* array(
* array('A', 'FFF', 'K', 'Q', 'VVVVV',),
* array('B', 'G', 'L', 'R', 'W',),
* array('C', 'H', 'MM', 'S', 'X',),
* array('D', 'I', 'N', 'T', 'Y',),
* array('E', 'J', 'P', 'UUUU', 'Z',),
* );
*/
function transpose($rows)
{
$result = call_user_func_array('array_map', array_merge(array(null), $rows));
return $result;
}
/**
* Returns the matrix whose values are from the given array of rows by columns.
*
* @param array $rows (example)
* array(
* array( 'A', 'B', 'C', 'D', 'E',),
* array( 'FFF', 'G', 'H', 'I', 'J',),
* array( 'K', 'L', 'MM', 'N', 'P',),
* array( 'Q', 'R', 'S', 'T', 'UUUU',),
* array('VVVVV', 'W', 'X', 'Y', 'Z',),
* );
* @param array $glue
* rows => string, separator that glues rows together
* cols => string, separator that glues columns together
* @param string $leadingWhite indentation of the matrix
* @return string (example)
* '
* A, B, C, D, E
* FFF, G, H, I, J
* K, L, MM, N, P
* Q, R, S, T, UUUU
* VVVVV, W, X, Y, Z
* ';
*/
function rowsByColumnsToMatrix($rows, $glue = array('rows' => "\n", 'cols' => ','), $leadingWhite = ' ')
{
$format = array_map(function ($row)
{
$max = max(array_map('strlen', $row));
return '%'. $max .'s';
}, transpose($rows));
$format = $leadingWhite . implode($glue['cols'] . ' ', $format);
$format = array_fill(0, count($rows), $format);
$format = implode($glue['rows'], $format);
$result = call_user_func_array('array_merge', $rows);
$result = call_user_func_array('sprintf', array_merge(array($format), $result));
$result = "$glue[rows]$result$glue[rows]";
return $result;
}
Here is a demo page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<pre>
<?php
require_once 'matrix.php';
$input = '
A, B, C, D, E
FFF, G, H, I, J
K, L, MM, N, P
Q, R, S, T, UUUU
VVVVV, W, X, Y, Z
';
$rows = matrixToRowsByColumns($input);
//$rows = transpose($rows);
$output = rowsByColumnsToMatrix($rows);
$input = var_export($input, true);
$output = var_export($output, true);
echo "<hr>\$input = $input;";
echo "<hr>\$output = $output;";
echo '<hr>$output ' . ($output === $input ? '=' : '!') . '== $input';
?>
</pre>
</body>
</html>
whose result is
$input = ' A, B, C, D, E FFF, G, H, I, J K, L, MM, N, P Q, R, S, T, UUUU VVVVV, W, X, Y, Z ';
$output = ' A, B, C, D, E FFF, G, H, I, J K, L, MM, N, P Q, R, S, T, UUUU VVVVV, W, X, Y, Z ';
$output === $input
After uncommenting the transposition line, the result is
$input = ' A, B, C, D, E FFF, G, H, I, J K, L, MM, N, P Q, R, S, T, UUUU VVVVV, W, X, Y, Z ';
$output = ' A, FFF, K, Q, VVVVV B, G, L, R, W C, H, MM, S, X D, I, N, T, Y E, J, P, UUUU, Z ';
$output !== $input