Ale Exc
Ale Exc

Reputation: 135

Most efficient way to create a 2d matrix from a 1d array in PHP

Given an array of strings, such as $a:

$a = array("zero", "one", "cat");

I'm looking to create array $b, populated "along the diagonal" with values from $a:

$b[0] = ["zero", "-", "-"]
$b[1] = ["-", "one", "-"]
$b[3] = ["-", "-", "cat"]

So far, I have:

function matrix($m, $n, $value) {
  return array_fill(0, $m, array_fill(0, $n, $value));
} // create a matrix (m,n) of $value

$a = array("zero", "one", "cat");  
$b = matrix(count($a),count($a),"'-'");  // create $b, filled with '-'

for($i = 0; $i < count($a); $i++){
  $b[$i][$i] = $a[$i];
} // fill matrix b with strings from a, along the diagonal

print_r($b);

In practice $a is going to be quite large, so I'm looking for a method with the lowest chance of bringing a server to its knees.

(Extra thanks given if you explain your version as if I were 8 years old.)

Upvotes: 2

Views: 719

Answers (2)

Pablo Martinez
Pablo Martinez

Reputation: 2180

I don't know if is more efficient (you have to measure it with microtime()).

Use Array Fill maybe its easier to write or understand:

$a = array("zero", "one", "cat");
$elements=count($a);
//we create the matrix and fill it with "-"
$matrix=array_fill(0,$elements,array_fill(0,$elements,"-");)
//now we have a matrix $elements x $elements (in this case will be 3x3) filled by "-"
// -  -  -
// -  -  -
// -  -  -

And now we put the numbers

for($i = 0; $i < $elements; $i++){
  $matrix[$i][$i] = $a[$i];
}

Upvotes: 2

Explosion Pills
Explosion Pills

Reputation: 191779

A method that "does not bring a server to its knees" in my opinion would avoid function calls and would also not use recursion, even though both may look cleaner in terms of code. Either way, this is a fairly simple problem.

First, we create our dashes array:

$dashes = array_fill(0, count($a), array_fill(0, count($a), '-'));

You may notice a pattern based on dimensions:

0,0    1,0    2,0
0,1    1,1    2,1
0,2    1,2    2,2

Specifically, the X and Y coordinates match along the diagonal. That's handy because we only have to know one or the other to know the slot to insert into our dashes array. The index of the item in $a qualifies as either (and both):

foreach ($a as $num => $item) {
   $dashes[$num][$num] = $item;
}

Upvotes: 3

Related Questions