views:

790

answers:

4

I need to explode by "," then ":". Easy enough...

$alttitle = "35:title1,36:title2, 59:title5"
$replacetitles = explode(",",$alttitle);
for ($i = 0 ; $i < count($replacetitles) ; $i++) {
   $replacetitle[] = explode(":", $replacetitles[$i]);
}

Which produces...

Array ( [0] => Array ( [0] => 35 [1] => title1 ) [1] => Array ( [0] => 36 [1] => title2 ) [2] => Array ( [0] => 59 [1] => title5 ) )

...but the number 35,36,59 are unique so I want this to become the key for the array?

Array ( [35] => title1 [36] => title2 [59] => title5 )

A: 

After your code you can add this:

$ar = array();
for ($i = 0; $i < count($replacetitle); $i++) {
    $ar[$replacetitle[$i][0]] = $replacetitle[$i][1];
}
RaYell
it is generally better to be in the habit of not using count (or other functions) on a fixed value in a loop expression. for ($i = 0, $t = count($replacetitle); $i < $t; $i++) {
OIS
This one is probably one of the least efficient solution. Your adding a another loop to create something you should of done first.
Andrew Moore
thank you very much!
EddyR
@Andrew Moore can you please show me your solution?
EddyR
+4  A: 

Simply set it while looping:

$alttitle = "35:title1,36:title2, 59:title5"
$tmptitles = explode(",",$alttitle);

$replacetitle = array();
foreach($tmptitles as $tmptitle) {
   $tmparr = explode(":", trim($tmptitle));
   $replacetitle[intval($tmparr[0])] = trim($tmparr[1]);
}

With the above, you will create your array a minimum number of iterations.

Andrew Moore
if you add a `trim` to `$tmparr[0]`, this will be the IMHO most elegant solution.
Boldewyn
heh, sorry there seems to be a lag where I am. How do I split more than 1 correct answer?! :)
EddyR
**@EddyR:** You can't. Chose the one that suits you best, which would be usually the community chose.
Andrew Moore
A: 

Here's my take

$alttitle  = "35:title1,36:title2, 59:title5";

$entries   = preg_split( "/ *, */", $alttitle );
$flattened = array();

for ( $i = 0, $l = count( $entries ); $i < $l; $i++)
{
  list( $index, $value ) = explode( ':', $entries[$i] );
  $flattened[$index] = $value;
}

print_r( $flattened );

EDIT

Now with speed test vs explode/trim

$testData = implode( ',', array_fill( 1, 10000, "a,b, c,  d" ) );

$start = microtime( true );
$entries = explode( ",", $testData );
$ouptput = array();

for ( $i = 0, $l = count( $entries ); $i < $l; $i++ )
{
  $output[] = trim( $entries[$i] );
}
echo "explode/trim test took: ", ( microtime( true ) - $start ), ' seconds<br>';

unset( $start, $entries, $output );

$start = microtime( true );
$entries = preg_split( "/ *, */", $testData );
$ouptput = array();

for ( $i = 0, $l = count( $entries ); $i < $l; $i++ )
{
  $output[] = $entries[$i];
}
echo "preg_split test took: ", ( microtime( true ) - $start ), ' seconds<br>';
Peter Bailey
preg_split is much less performant than explode followed by trim.
Boldewyn
Are you sure about that? Try the test I posted above.
Peter Bailey
**@Peter Bailey:** Your code fails to handle input such as `32:My Nice Book, 57:The Terror Of The Seas, 92: Hello World`
Andrew Moore
@Andrew - thanks, good catch. Fixed.
Peter Bailey
**@Peter Bailey:** And in the interest of keeping the result the same as using `trim`, you should use `preg_split( "/\s*,\s*/m", $alttitle );`
Andrew Moore
Well, technically speaking if I wanted to 100% mimic trim(), it would need to be `"/[\\s\\r\\n\\0\\x0B]*,[\\s\\r\\n\\0\\x0B]*/"` but I'll leave such minutiae as an exercise for EddyR
Peter Bailey
On my machine (WinXP, Core2Duo) explode+trim needs about .04 seconds and preg_split needs .047 seconds with your test. Small, but significant.
Boldewyn
Significant? *Really?* .007 seconds on 10,000 iterations when the likely sample data set is going to be far less? I think you worry too much about premature optimizations. P.S. with multiple runs, the preg_split test ran an average of 60% faster, although in some test runs the explode/trim test was faster, which for me even further highlights why niggling over this sort of thing is academic at best.
Peter Bailey
A: 

Here is another but probably overkill alternative.

if (!preg_match_all('/([0-9]+)\s*:\s*([^,]+)/', $alttitle, $matches)) {
    //not valid   
}

$array = array_combine($matches[1], $matches[2]);
print_r($array);
Tom Haigh