Сортировка фрагмента ассоциативного многомерного массива с помощью цифровых клавиш - PullRequest
0 голосов
/ 26 июня 2018

В этой функции assignView($sums,$count) Я хочу сделать INSERT INTO для SAP (партнера) с наименьшим количеством просмотров.

Проблема, с которой я сталкиваюсь, состоит в том, чтобы вырезать элементы из массива $count, чтобы иметь возможность их сортировать. Думаю, я мог бы отсортировать его в SQL-запросе, но проблема с выделением правильных элементов prio сохраняется.

Все работает так, как задумано, до той части в функции assignView($sums,$count), где я хочу выполнить array_slice.

Ничего, конечно, не заложено в камне. Если вы видите лучший или более эффективный способ достижения моей цели, не стесняйтесь делиться:)

Я думал об изменении функции findKey($haystack,$needle) путем добавления логики среза, но поскольку клавиша SAP в $count является числовой, я рисую пробел.

Есть какие-либо предложения о том, как решить эту проблему?

$sql = "
    SELECT
        `partner`,
        `day_slice0006` as q1,
        `day_slice0612` as q2,
        `day_slice1218` as q3,
        `day_slice1800` as q4
    FROM `sap_quotas`
    WHERE `servertime` < UNIX_TIMESTAMP()
    GROUP BY `partner`";

if($stmt = $db->prepare($sql))
{

    $stmt->execute();
    $stmt->bind_result($partner,$q1,$q2,$q3,$q4);

    while($stmt->fetch())
    {

        $SAPshares[$partner]['00:00-06:00'] = $q1; // $partner is a unique id. ex. 3001
        $SAPshares[$partner]['06:00-12:00'] = $q2; // day_slice0006 hold a value from 1-3
        $SAPshares[$partner]['12:00-18:00'] = $q3; // corresponding to priorities
        $SAPshares[$partner]['18:00-00:00'] = $q4; // 1=(2*2), 2=(3*2), 3=n

    }
    $stmt->close();

    $SAPshares = array(
        3000 => array(
            '00:00-06:00' => 1,
            '06:00-12:00' => 1,
            '12:00-18:00' => 1,
            '18:00-00:00' => 1),
        3001 => array(
            '00:00-06:00' => 1,
            '06:00-12:00' => 1,
            '12:00-18:00' => 1,
            '18:00-00:00' => 1),
        3002 => array(
            '00:00-06:00' => 2,
            '06:00-12:00' => 2,
            '12:00-18:00' => 2,
            '18:00-00:00' => 2),
        3003 => array(
            '00:00-06:00' => 3,
            '06:00-12:00' => 3,
            '12:00-18:00' => 3,
            '18:00-00:00' => 3)
    ); // EDIT: Added a faked resultset

    $SAPs = array_keys($SAPshares); // Array with the partner id's

}

$sql = "
    SELECT
        COUNT(`id`) AS cnt,
        `partner`,
        `servertime`,
        DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%Y-%m-%d') AS today,
        CASE WHEN DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%H:%i') <  '06:00:00'
                THEN '00:00-06:00'
             WHEN DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%H:%i') >= '06:00:00'
             && DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%H:%i') < '12:00:00'
                THEN '06:00-12:00'
             WHEN DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%H:%i') >= '12:00:00'
             && DATE_FORMAT(FROM_UNIXTIME(`servertime`),'%H:%i') < '18:00:00'
                THEN '12:00-18:00'
             ELSE '18:00-00:00' END AS timesegment
    FROM `sap_daily_stats`
    GROUP BY `partner`, `today`, `timesegment`
    HAVING today = CURDATE()";

if($stmt = $db->prepare($sql))
{

    $stmt->execute();
    $stmt->bind_result($cnt,$partner,$servertime,$today,$timesegment);


    while($stmt->fetch())
    {

//      example format: $count[3001][1]['12:00-18:00'] = n
        $count[$partner][$timesegment][$SAPshares[$partner][$timesegment]] = $cnt;

    }
    $stmt->close();
}
$db->close();

$count = array(
3000 => array(
    '00:00-06:00' => array(1 => 9),
    '06:00-12:00' => array(1 => 4),
    '12:00-18:00' => array(1 => 1)),
3001 => array(
    '00:00-06:00' => array(1 => 12),
    '06:00-12:00' => array(1 => 4),
    '12:00-18:00' => array(1 => 1)),
3002 => array(
    '00:00-06:00' => array(2 => 6),
    '06:00-12:00' => array(2 => 4),
    '12:00-18:00' => array(2 => 1)),
3003 => array(
    '06:00-12:00' => array(3 => 4),
    '12:00-18:00' => array(3 => 1))
); // EDIT: Added a faked resultset

$hour = date('H',time());
switch(true)
{

    case $hour >= 18: // '18:00-00:00'

        $sums = SAPSums($SAPs,$count,'18:00-00:00');
        assignView($sums,$count);
        break;

    case $hour >= 12: // '12:00-18:00'

        $sums = SAPSums($SAPs,$count,'12:00-18:00');
        assignView($sums,$count);
        break;

    case $hour >= 6:  // '06:00-12:00'

        $sums = SAPSums($SAPs,$count,'06:00-12:00');
        assignView($sums,$count);
        break;

    default:          // '00:00-06:00'

        $sums = SAPSums($SAPs,$count,'00:00-06:00');
        assignView($sums,$count);

}

// functions below ###############################################################

function findKey($haystack,$needle) // If key exists in multidimentional array
{

    foreach($haystack as $key => $item)
    {

        if($key == $needle)
        {

            echo 'yes, it exists';
            return true;

        }
        elseif(is_array($item) && findKey($item,$needle))
        {

            return true;

        }

    }

    return false;

}

// Sum up the count from the different prio categories
function SAPSums($SAPs,$count,$segment)
{

    foreach($SAPs as $SAPID)
    {

        $sum1 += array_sum(array_column_recursive($count[$SAPID][$segment],1));
        $sum2 += array_sum(array_column_recursive($count[$SAPID][$segment],2));
        $sum3 += array_sum(array_column_recursive($count[$SAPID][$segment],3));

    }
    return array($sum1,$sum2,$sum3);

}

function assignView($sums,$count)
{

    if($sums[0] < ($sums[2]*2))
    {

        $giveViewTo = 1;
        echo "prio 1";

    }
    elseif($sums[1] < ($sums[2]*2))
    {

        echo findKey($count,2);
        $giveViewTo = 2;
        echo "prio 2";

    }
    else
    {

        $giveViewTo = 3;
        echo "prio 3";

    }
    return "give to: {$giveViewTo}<br>";

}

function array_column_recursive(array $haystack,$needle)
{

    $found = [];
    array_walk_recursive($haystack,
        function($value, $key) use (&$found, $needle)
        {

            if($key == $needle) $found[] = $value;

        }

    );
    return $found;

}

1 Ответ

0 голосов
/ 27 июня 2018

Этим утром, по дороге на работу, меня поразило. Поскольку проблема, по сути, связана с большим количеством информации, чтобы иметь возможность сортировки, мне просто нужно отменить текущий временной сегмент, и проблема исчезнет.

Теперь. Это работает для этой конкретной проблемы, но я так же легко могу видеть исходную проблему как действительную в каком-то другом контексте, например, при работе с ежедневной статистикой, поэтому я не буду отмечать ее как решенную, и я все еще ищу ответ.

...