Reputation: 13224
I would like to repeat each value 3 times and put it in the correct order. In place of each original element 3 copies of itself should take its place.
Given the following one-dimensional array of strings:
$chars = ["a", "b", "c"];
So result would be:
$duplicatedChars = ["a", "a", "a", "b", "b", "b", "c", "c", "c"];
I have tried working with str_repeat()
, but this does not create separate strings.
This attempt doesn't create enough elements, it only repeats the string within each element.
$result = [];
foreach ($chars as $char) {
$result[] = str_repeat($char, 3);
}
Upvotes: 2
Views: 1021
Reputation: 47904
I'll add a few more techniques for completeness. Solutions that leverage the magic number 3 will be more scalable, but I'll also show some less scalable approaches which repeat a variable or an action 3 times.
A body-less loop pushing each element into a new array 3 times: (Demo)
$result = [];
foreach (array_chunk($chars, 1) as [0 => $result[], 0 => $result[], 0 => $result[]]);
var_export($result);
A functional loop calling array_fill()
and array_merge()
on every iteration: (Demo)
var_export(
array_reduce(
$chars,
fn($result, $v) => array_merge($result, array_fill(0, 3, $v)),
[]
)
);
Transpose and flatten 3 copies of the input array: (Demo)
var_export(
array_merge(...array_map(null, $chars, $chars, $chars))
);
or: (Demo)
var_export(
array_merge(...array_map(null, ...array_fill(0, 3, $chars)))
);
Looped calls of array_fill()
with its returned array spread as parameters of array_push()
: (Demo)
$result = [];
foreach ($chars as $char) {
array_push($result, ...array_fill(0, 3, $char));
}
var_export($result);
Looped calls of array_pad()
with a growing maximum array count: (Demo)
$result = [];
foreach ($chars as $char) {
$result = array_pad($result, count($result) + 3, $char);
}
var_export($result);
A for()
loop calling array_fill()
and array_splice()
on every iteration: (Demo)
for ($i = count($chars) - 1; $i >= 0; --$i) {
array_splice($chars, $i, 1, array_fill(0, 3, $chars[$i]));
}
var_export($chars);
Upvotes: 1
Reputation: 78994
You can get by without the loops as array_fill
will take an array:
$result = array_merge(...array_fill(0, 3, $chars));
Or you could use a string:
$result = str_split(str_repeat(implode($chars), 3));
If needed just sort
to get the order that you show.
Upvotes: 0
Reputation: 43999
Since you know the number of repeats, you can get the desired output using a foreach
and for
$repeat + 1
times; push the char to $result
<?php
$chars = ["a", "b" , "c"];
$result = [];
$repeat = 3;
foreach ($chars as $char) {
for ($i = 0; $i < $repeat; $i++) {
$result[] = $char;
}
}
var_dump($result);
array(9) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
[2]=>
string(1) "a"
[3]=>
string(1) "b"
[4]=>
string(1) "b"
[5]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "c"
[8]=>
string(1) "c"
}
@Barmar's answer has the same 'idea', but uses
array_merge
instead off $result[] = ;
array_fill
instead off an extra for
.Upvotes: 1
Reputation: 781096
str_repeat
creates a single string, not an array.
Use array_fill()
to create an array with N copies of a value. Then append the array to the result.
foreach ($chars as $char) {
$result = array_merge($result, array_fill(0, 3, $char));
}
Upvotes: 2