Я создаю галерею изображений и хочу бросить рекламные баннеры в случайных точках, чтобы продвигать определенные предложения для пользователей. Учитывая, что следующий массив поступает из запроса базы данных:
Array
(
[0] => Array
(
[insertDate] => 2014-11-10 11:22:58
[keyword] => standard
[mediaClass] => image
[mediaURL] => http://image1.jpg
[promoURL] =>
)
[1] => Array
(
[insertDate] => 2014-11-10 11:23:08
[keyword] => promo
[mediaClass] => image
[mediaURL] => http://image2.jpg
[promoURL] => http://www.google.com
)
[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] =>
)
[4] => Array
(
[insertDate] => 2014-07-08 11:23:38
[keyword] => promo
[mediaClass] => image
[mediaURL] => http://image5.jpg
[promoURL] => http://www.google.com
)
[5] => Array
(
[insertDate] => 2014-07-08 11:23:48
[keyword] => standard
[mediaClass] => image
[mediaURL] => http://image6.jpg
[promoURL] =>
)
)
Я пытаюсь сделать две вещи;
1)
Убедитесь, что на 5 стандартных изображений есть только одно промо- изображение (в этом примере 2, поэтому нужно будет удалить/отфильтровать из массива с помощью ключевого слова). Это делается для того, чтобы избежать спама с помощью слишком большого количества рекламных баннеров.
2)
Раммируйте положение любых изображений с ключевым словом promo, но сохраняйте порядок изображений со стандартным ключевым словом insertDate.
Принимая во внимание, что размер этих наборов результатов всегда будет отличаться, что было бы лучшим способом программно достичь этого?
edit: Я создал следующую функцию для решения первой части:
function limitMediaPromos($array, $key, $value, $limit)
{
// count the number of promo images
if($count = $this->countElementsWithValue($array, $key, $value))
{
// find the avg number of promos per media set
$avg = floor((count($array) / $count));
// remove promo element if avg is over set limit
if($avg > $limit)
{
$array = $this->removeElementWithValue($array, $key, $value);
}
}
return $array;
}
Для лучшей сортировки производительности на стороне базы данных и удаления функции mediaSort и usort ($ medias, 'mediaSort'); ниже.
function isMedia($var) {
return empty($var['promoURL']);
}
function isPromo($var)
{
return !empty($var['promoURL']);
}
function mediaSort($mediaOne, $mediaTwo)
{
return (strtotime($mediaOne['insertDate']) <= strtotime($mediaTwo['insertDate']));
}
function getImages($input)
{
// Get the promos. O(n).
$promos = array_filter($input, "isPromo");
// randomize them. O(n).
shuffle($promos);
// Get the medias. O(n)
$medias = array_filter($input, "isMedia");
// Sort them (ideally sort it on the database side and skip this step). O(n log n)
usort($medias, 'mediaSort');
$promoOdds = 1/5;
$promoGap = 5;
$returnIndex = 0;
$return = array();
foreach ($medias as $media) {
if (is_null($lastPromoIndex)
|| $returnIndex > $lastPromoIndex + $promoGap
) {
if (rand(1,1/$promoOdds) == 1) {
$return[] = array_pop($promos);
$lastPromoIndex = $returnIndex;
}
}
$return[] = $media;
$returnIndex++;
}
if (is_null($lastPromoIndex)
|| $returnIndex > $lastPromoIndex + $promoGap
) {
$return[] = array_pop($promos);
}
return $return;
}
print_r(getImages($input));