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);
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);
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
)