简体   繁体   English

在PHP中过滤和排序多维数组

[英]Filter and Sort a multidimensional array in PHP

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 array comes from a database query: 给定以下数组来自数据库查询:

    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] => 
            )
     )

I am trying to do two things; 我正在尝试做两件事;

1) 1)

Ensure there is only one promo image per 5 standard images (in this example there are 2 so one would need to be removed/filtered from the array using the keyword key). 确保每5张标准图片中只有一张促销图片(在此示例中有2张,因此需要使用关键字key从阵列中删除/过滤一张)。 This is to avoid spamming the user with too many promotional banners. 这是为了避免向用户发送过多的促销标语。

2) 2)

Ramdomise the position of any images with the promo keyword but still maintain the order of images with the standard keyword by insertDate. 使用promo关键字随机排列任何图像的位置,但仍通过insertDate保持标准关键字的图像顺序。

Bearing in mind the size of these result sets will always differ, what would be the best way to programmatically achieve this? 考虑到这些结果集的大小总是会有所不同,以编程方式实现这一目标的最佳方法是什么?

edit: I created the following function to tackle the first part: 编辑:我创建了以下功能来解决第一部分:

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;
}

For better performance sort on the database side, and remove the mediaSort function and the usort($medias, 'mediaSort'); 为了获得更好的性能,请在数据库侧进行排序,并删除mediaSort函数和usort($ medias,'mediaSort');。 below. 下面。

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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM