Home > database >  PHP - Implode as array
PHP - Implode as array

Time:09-30

I have a an array like so:

$fruit = array('Apple', 'Orange', 'Banana');

I would like to combine the array with a separator similar to implode but without converting the result to a string.

So instead of

implode('.', $fruit); // 'Apple.Orange.Banana'

the result should be:

array('Apple', '.', 'Orange', '.', 'Banana');

This could probably be achieved with loops, however, I am looking for the best possible solution. Maybe there is a native function that can accomplish that which I do not know of? Thanks in advance!

CodePudding user response:

You can implode based on |.|(period character surrounded by pipes) and then explode on the | pipe character.

<?php

$fruits = array('Apple', 'Orange', 'Banana');

$d = explode("|", implode('|.|', $fruits));

print_r($d);

Online Demo

Update:

As @RiggsFolly mentioned in the comments, you can use a very unlikely character like chr(1) as a delimiter.

<?php
$fruits = array('Apple', 'Orange', 'Banana');
$sep = chr(1);
$d = explode($sep, implode($sep.'.'.$sep, $fruits));

print_r($d);

Online Demo

CodePudding user response:

Use array_splice() with a reversed for loop

Remember to remove 1 from count($fruit) so we won't add another . at the end of the array

<?php

$fruit = [ 'Apple', 'Orange', 'Banana' ];
for ($i = count($fruit) - 1; $i > 0; $i--) {
    array_splice($fruit, $i, 0, '.');
}

var_dump($fruit);
array(6) {
  [0]=>
  string(5) "Apple"
  [1]=>
  string(1) "."
  [2]=>
  string(6) "Orange"
  [3]=>
  string(1) "."
  [4]=>
  string(6) "Banana"
}

CodePudding user response:

Alternative

Leaning on the array_* functions, you could consider the following:

function interleave(string $sep, array $arr): array {
  return array_slice(array_merge(...array_map(fn($elem) => [$sep, $elem], $arr)), 1); 
}

Due to the use of inbuilt functions and no explicit looping, it exceeds the speed of the looping array_splice implementation around the 10 element mark, so the trade-off between terse implementation and performance may be worth it in your case.

Explanation

When called like so:

interleave('.', ['Apple', 'Orange', 'Banana']);

does the following (from the inside out):

Map

Map each element to a pair ['.', $elem]:

$mapped = array_map(fn($elem) => ['.', $elem], ['Apple', 'Orange', 'Banana']);

resulting in:

Array
(
    [0] => Array
        (
            [0] => .
            [1] => Apple
        )

    [1] => Array
        (
            [0] => .
            [1] => Orange
        )

    [2] => Array
        (
            [0] => .
            [1] => Banana
        )

)

Merge

Flatten the array using array_merge taking advantage of the fact that, from the documentation:

If [...] the arrays contain numeric keys, the later value will not overwrite the original value, but will be appended.

$merged = array_merge(...$mapped);

resulting in:

Array
(
    [0] => .
    [1] => Apple
    [2] => .
    [3] => Orange
    [4] => .
    [5] => Banana
)

Slice

Slice off the first extra separator:

$sliced = array_slice($merged, 1);

resulting in:

Array
(
    [0] => Apple
    [1] => .
    [2] => Orange
    [3] => .
    [4] => Banana
)
  • Related