Merge array into established array at random index

2019-09-06 06:42发布

问题:

I'm building an image gallery and want to throw some promo banners in at random points to promote certain offers to users. Given the following two arrays have been filtered from a database query:

Media images array:

 Array
 (
      [0] => Array
         (
             [insertDate] => 2014-11-10 11:22:58
             [keyword] => standard
             [mediaClass] => image
             [mediaURL] => http://image1.jpg
             [promoURL] => 
         )

      [2] => Array
         (
             [insertDate] => 2014-11-10 11:23:18
             [keyword] => standard
             [mediaClass] => image
             [mediaURL] => http://image3.jpg
             [promoURL] => 
         )

      [3] => Array
         (
             [insertDate] => 2014-11-10 11:23:28
             [keyword] => standard
             [mediaClass] => image
             [mediaURL] => http://image4.jpg
             [promoURL] => 
         )

      [5] => Array
         (
            [insertDate] => 2014-11-10 11:23:48
            [keyword] => standard
            [mediaClass] => image
            [mediaURL] => http://image6.jpg
            [promoURL] => 
         )
    )

Promo images array:

    Array
    (
       [1] => Array
          (
            [insertDate] => 2014-11-10 11:23:08
            [keyword] => promo
            [mediaClass] => image
            [mediaURL] => http://image2.jpg
            [promoURL] => http://www.google.com
          )

       [4] => Array
          (
            [insertDate] => 2014-11-10 11:23:38
            [keyword] => promo
            [mediaClass] => image
            [mediaURL] => http://image5.jpg
            [promoURL] => http://www.google.com
          )
     )

How can I insert the promo images into the media images array at random indexes while maintaining the sort order by insertDate of the media images?

i.e Adding promo banners into a timeline of images.

回答1:

This is what I would do:

<?php
$promo = Array (
   Array ('insertDate' => '2014-11-10 11:23:08', 'keyword' => 'promo', 'mediaClass' => 'image', 'mediaURL' => 'http://image2.jpg', 'promoURL' => 'http://www.google.com'),
   Array ('insertDate' => '2014-11-10 11:23:38', 'keyword' => 'promo', 'mediaClass' => 'image', 'mediaURL' => 'http://image5.jpg', 'promoURL' => 'http://www.google.com')
 );

$media = Array (
  Array ('insertDate' => '2014-11-10 11:22:58', 'keyword' => 'standard', 'mediaClass' => 'image', 'mediaURL' => 'http://image1.jpg', 'promoURL' => '', ),
  Array ('insertDate' => '2014-11-10 11:23:18', 'keyword' => 'standard', 'mediaClass' => 'image', 'mediaURL' => 'http://image3.jpg', 'promoURL' => '', ),
  Array ('insertDate' => '2014-11-10 11:23:28', 'keyword' => 'standard', 'mediaClass' => 'image', 'mediaURL' => 'http://image4.jpg', 'promoURL' => '', ),
  Array ('insertDate' => '2014-11-10 11:23:48', 'keyword' => 'standard', 'mediaClass' => 'image', 'mediaURL' => 'http://image6.jpg', 'promoURL' => '', )
);

//sort the promo in random order. This ensures they go into media in random order
shuffle($promo);

//get random keys to insert the promo image before
$randKeys = array_rand($media, count($promo));
//sort by the random key value in reverse. By inserting in reverse order,
//we won't have an issue with needing to increment keys to prevent two promo
//images ending up next to each other. Also, this is why we shuffle the promo
//array above, so the promo images go in random order because this is no longer random.
rsort($randKeys);

//loop over the random keys and insert the next promo image before each key
foreach($randKeys as $key){
    //get the first promo image and remove it
    $promoImage = array_shift($promo);
    //splice the promo image into the media array
    array_splice($media, $key, 0, array($promoImage));
}

//display
print_r($media);

Only thing to note is that both my media and promo arrays are numeric index based starting at zero and contiguous which is default for an array and not like the arrays you posted where they 1 and 4 keys are removed from the media array.



回答2:

If you have no tons of images (say, max. 100), feel free to create arrays "by hand". First, you should create an array, which contains the positions of the promo items. You know the number of items in the content array, the number of the items in the promo array; the sum of them will be the final array's size. Figure out some smart math, which calculates the positions of promo items (e.g. don't put promo in the first and last place, don't put two promo items in neighbour positions, maybe you have to unset() some promo items, if there're more promo items than content items).

If you have the promo positions, you may walk trhough on the content items, copying them into the final array. Before content copy, you should check whether the current position is reserved for a promo item, if yes, promo item should copied first. Voila, you have a final item list, promo items interleaved.

PHP is a good choice for these kind of tasks, thanks to autovivification (you don't have to create parent nodes for a deep-placed element). The programming, especially web pages are:

  1. dig some data items into array (from SQL, JSON, API call)
  2. create final array with different index (maybe it occurs merging/sum items)
  3. sort, filter, lookup other arrays for other fields
  4. display final array

Similar tasks appears in job interview questions (scan through an array, and count/sum/merge something).