开发者

most efficient method of turning multiple 1D arrays into columns of a 2D array

As I was writing a for loop earlier today, I thought that there must be a neater way of doing this... so I figured I'd ask. I looked briefly for a duplicate question but didn't see anything obvious.

The Problem:

Given N arrays of length M, turn them into a M-row by N-column 2D array

Example:

$id   = [1,5,2,8,6]
$name = [a,b,c,d,e]
$result = [[1,a],
           [5,b],
           [2,c],
           [8,d],
           [6,e]]

My Solution:

Pretty straight forward and probably not optimal, but it does work:

<?php
// $row is returned from a DB query
// $row['<var>'] is a comma separated string of values
$categories = array();
$ids = explode(",", $row['ids']);
$names = explode(",", $row['names']);
$titles = explode(",", $row['titles']);
for($i = 0; $i < count($ids); $i++) {
    $categories[] = array("id" => $ids[$i],
                          "name" => $names[$i],
                          "title" => $titles[$i]);
}
?>

note: I didn't put the name => valu开发者_高级运维e bit in the spec, but it'd be awesome if there was some way to keep that as well.


Maybe this? Not sure if it's more efficient but it's definitely cleaner.

/*
Using the below data:

$row['ids'] = '1,2,3';
$row['names'] = 'a,b,c';
$row['titles'] = 'title1,title2,title3';
*/

$categories = array_map(NULL,
  explode(',', $row['ids']),
  explode(',', $row['names']),
  explode(',', $row['titles'])
);

// If you must retain keys then use instead:
$withKeys = array();

foreach ($row as $k => $v) {
    $v = explode(',', $v);

    foreach ($v as $k2 => $v2) {
        $withKeys[$k2][$k] = $v[$k2];
    }
}

print_r($categories);
print_r($withKeys);

/*
$categories:

array
  0 => 
    array
      0 => int 1
      1 => string 'a' (length=1)
      2 => string 'title1' (length=6)
...

$withKeys:

array
  0 =>
    array
      'ids' => int 1
      'names' => string 'a' (length=1)
      'titles' => string 'title1' (length=6)
...
*/

Just did a quick simple benchmark for the 4 results on this page and got the following:

// Using the following data set:
$row = array(
    'ids'       =>  '1,2,3,4,5',
    'names'     =>  'abc,def,ghi,jkl,mno',
    'titles'    =>  'pqrs,tuvw,xyzA,BCDE,FGHI'
);

/*
For 10,000 iterations,

Merge, for:
0.52803611755371

Merge, func:
0.94854116439819

Merge, array_map:
0.30260396003723

Merge, foreach:
0.40261697769165
*/


Yup, array_combine()

$result = array_combine( $id, $name );

EDIT

Here's how I'd handle your data transformation

function convertRow( $row )
{
  $length = null;
  $keys = array();

  foreach ( $row as $key => $value )
  {
    $row[$key] = explode( ',', $value );
    if ( !is_null( $length ) && $length != count( $row[$key] ) )
    {
      throw new Exception( 'Lengths don not match' );
    }
    $length = count( $row[$key] );

    // Cheap way to produce a singular - might break on some words
    $keys[$key] = preg_replace( "/s$/", '', $key );
  }

  $output = array();

  for ( $i = 0; $i < $length; $i++ )
  {
    foreach ( $keys as $key => $singular )
    {
      $output[$i][$singular] = $row[$key][$i];
    }
  }

  return $output;
}

And a test

$row = convertRow( $row );
echo '<pre>';
print_r( $row );
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜