5

I have an array:

$names = [
    "Ayush" , "Vaibhav", "Shivam",
    "Hacker", "Topper", "ABCD",
    "NameR", "Tammi", "Colgate",
    "Britney", "Bra", "Kisser"
];

And I have another variable

$addthis = "ADDTHIS";

How to make an array from these two so that after every three items in $names, the value of $addthis is added. So, I want this array as result from these two.

$result = [
    "Ayush", "Vaibhav", "Shivam", "ADDTHIS",
    "Hacker", "Topper", "ABCD", "ADDTHIS",
    "NameR", "Tammi", "Colgate", "ADDTHIS",
    "Britney", "Bra", "Kisser"
];
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Ayush Mishra
  • 506
  • 1
  • 4
  • 15

8 Answers8

4

"Oneliner", just for fun:

$new = array_reduce(
    array_map(
        function($i) use($addthis) { return count($i) == 3 ? array_merge($i, array($addthis)) : $i; },
        array_chunk($names, 3)
    ),
    function($r, $i) { return array_merge($r, $i); },
    array()
);
zerkms
  • 249,484
  • 69
  • 436
  • 539
2

Maybe an easier to understand solution:

// the parameters
$names = array( "Ayush" , "Vaibhav", "Shivam", "Hacker", "Topper",
            "ABCD",  "NameR", "Tammi", "Colgate", "Britney",
            "Bra", "Kisser");
$addThis = 'ADDTHIS';
$every = 3;

// how often we need to add this
$count = ceil(count($names) / $every) - 1;
for ($i = 0; $i < $count; $i++) {
    array_splice($names, $i * ($every + 1) + $every, 0, $addThis);
}

array_splice is exactly for modifying arrays (removing or adding items), preserves existing keys and is not doing any other operation on the array.

While other answers are for sure valid as well this should be the fastest and cleanest solution.

iRaS
  • 1,958
  • 1
  • 16
  • 29
  • Similar techniques ([one more rigid](https://stackoverflow.com/a/12520664/2943403), [one more dynamic](https://stackoverflow.com/a/73568281/2943403)) can be found at [Insert elements from one array (one-at-a-time) after every second element of another array (un-even zippering)](https://stackoverflow.com/q/12520272/2943403) – mickmackusa Sep 01 '22 at 23:20
  • An important point of distinction: The above answer [does not insert a new element AFTER every 3 elements](https://3v4l.org/X0drs), if it did, there would be another inserted element after the 12th/last element. It doesn't mean that it is wrong, in fact, it provides the asker's desired output. This comes down to ambiguity in the plain English expression of the task. – mickmackusa Sep 01 '22 at 23:43
1

Another oneliner ;)

$result = call_user_func_array(
    'array_merge', array_map(function($v) use ($addthis) {
        return $v + [4 => $addthis];
    }, array_chunk($names, 3))
); array_pop($result);

Demo

hakre
  • 193,403
  • 52
  • 435
  • 836
1

I concur with @iRaS's answer that it will be more direct/efficient to make iterated element insertions in a loop. I interpret the question as requiring an element to be inserted after every 10 elements -- in other words, if the array has exactly 20 elements, then 2 elements should be inserted. One after the 10nth element, then one after the 20th element.

By iterating from the back of the array, you can avoid keeping track of previously injected elements (which effectively push out the desired position of subsequently injected elements). I didn't use this approach while crafting a dynamic approach for a similar question.

Use a modulus-based calculation to determine the last insertion position, then decrement the position variable by the $every variable.

To test the accuracy of my snippet, just add and remove elements in the input array.

Code: (Demo)

$names = [
    "Ayush" , "Vaibhav", "Shivam",
    "Hacker", "Topper", "ABCD",
    "NameR", "Tammi", "Colgate",
    "Britney"//, "Bra"//, "Kisser"
];
$addThis = 'ADDTHIS';
$every = 3;

for (
    $count = count($names), $pos = $count - ($count % $every);
    $pos > 0;
    $pos -= $every
) {
    array_splice($names, $pos, 0, $addThis);
}
var_export($names);

Output:

array (
  0 => 'Ayush',
  1 => 'Vaibhav',
  2 => 'Shivam',
  3 => 'ADDTHIS',
  4 => 'Hacker',
  5 => 'Topper',
  6 => 'ABCD',
  7 => 'ADDTHIS',
  8 => 'NameR',
  9 => 'Tammi',
  10 => 'Colgate',
  11 => 'ADDTHIS',
  12 => 'Britney',
)

P.S. If you don't want to add the extra tail element (the array shouldn't end with an "ADDTHIS" element), then use this code as the first parameter of the for():

$count = count($names), $pos = $count - (($count % $every) ?: $every);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

I have the ANSWER for anyone curious, I've just done a function that randomizes an array.

function randomize($array){
    $randomized=array(); //start a new array
    foreach ($array as $key=>$val){ ///loop thru the array we randomize
        if($key % 2 == 0){   ////if the key is even
            array_push($randomized,$val);///push to back
        }else{ ////if the key is odd
            array_unshift($randomized,$val); ///push to front
        }
    }
    return $randomized;
}///randomize

Basically what we are doing is creating a new randomized array, looping through the array we pass, tracking an interator and as we loop thru if the key is even we send that array value to the back, if its odd we send that to the front.

Trey Tyler
  • 273
  • 2
  • 10
-1
$result = array();
$cnt = 0;
foreach ($names AS $val) {
    $result[] = $val;
    if ($cnt >=3) {
        $result[] = $addthis;
        $cnt = 0;
    }
    $cnt++;
}
newman
  • 2,689
  • 15
  • 23
-1

Loop through and use modulo for checking for 3. element: After that use splice to insert an element between two element

    foreach($result as $k=>$value){
 if(($k+1)%3==0){
   array_splice($arrayvariable, $k+1, 0, "ADDTHIS");
 }
}
Dávid Szabó
  • 2,235
  • 2
  • 14
  • 26
  • This answer [does not provide the desired result](https://3v4l.org/kPdhu) because it doesn't account for previously inserted elements – mickmackusa Sep 02 '22 at 00:43
-2

One thing you do not want to do is assume that every key in your array is numeric and that it accurately represents the offset of each element. This is wrong, because PHP arrays are not like traditional arrays. The array key is not the offset of the element (i.e. it does not determine the order of elements) and it does not have to be a number.

Unfortunately, PHP arrays are ordered hashmaps, not traditional arrays, so the only way to insert a new element in the middle of the map is to create a brand new map.

You can do this by using PHP's array_chunk() function, which will create a new array of elements, each containing up to a designated number of elements, form your input array. Thus we create an array of arrays or chunks of elements. This way you can iterate over the chunks and append them to a new array, getting your desired effect.

$names = array( "Ayush" , "Vaibhav", "Shivam", "Hacker", "Topper",
                "ABCD",  "NameR", "Tammi", "Colgate", "Britney",
                "Bra", "Kisser");

$addthis = "ADDTHIS";

$result = array();

foreach (array_chunk($names, 3) as $chunk) { // iterate over each chunk
    foreach ($chunk as $element) {
        $result[] = $element;
    }
    // Now push your extra element at the end of the 3 elements' set
    $result[] = $addthis;
}

If you wanted to preserve keys as well you can do this....

$names = array( "Ayush" , "Vaibhav", "Shivam", "Hacker", "Topper",
                "ABCD",  "NameR", "Tammi", "Colgate", "Britney",
                "Bra", "Kisser");

$addthis = "ADDTHIS";

$result = array();

foreach (array_chunk($names, 3, true) as $chunk) { // iterate over each chunk
    foreach ($chunk as $key => $element) {
        $result[$key] = $element;
    }
    // Now push your extra element at the end of the 3 elements' set
    $result[] = $addthis;
}

This perserves both order of the elements as well as keys of each element. However, if you don't care about the keys you can simply use the first example. Just be careful that numeric keys in order will cause you a problem with the second approach since the appended element in this example is assuming the next available numeric key (thus overwritten on the next iteration).

Sherif
  • 11,786
  • 3
  • 32
  • 57
  • in the question there was no word about assoc array and php also has indexed arrays. on the other hand: this would create a new array and array_chunks that are bascially wasted memory - and my version will also preserve the existing keys. – iRaS Oct 15 '18 at 09:21
  • This answer [does not provide the desired output](https://3v4l.org/QdqvP). – mickmackusa Sep 02 '22 at 00:46