Christophvh
Christophvh

Reputation: 13224

Duplicate each string in a flat array N times

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

Answers (4)

mickmackusa
mickmackusa

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

AbraCadaver
AbraCadaver

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

0stone0
0stone0

Reputation: 43999

Since you know the number of repeats, you can get the desired output using a foreach and for

  1. Loop through the original array
  2. 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"
}

Try it online!


@Barmar's answer has the same 'idea', but uses

  • array_merge instead off $result[] = ;
  • array_fill instead off an extra for.

Upvotes: 1

Barmar
Barmar

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

Related Questions