Move 2nd level sub-array to the top of the 1st level multidimentional array based on value of the sub-array - Hack The Tech - Latest News related to Computer and Technology

Hack The Tech - Latest News related to Computer and Technology

Get Daily Latest News related to Computer and Technology and hack the world.

Thursday, June 10, 2021

Move 2nd level sub-array to the top of the 1st level multidimentional array based on value of the sub-array

I'm looping through a multidimensional array and am left with some values.

This is the complete PHP code.


<?php 
/**
 * Each designer is required 3x per week, 
 * add their name 3 times to allow for the count.
 * 
 * [array_pop]  removes the designer from the sub-array
 * u[sort($designers, "sortByTotalItems")] then moves the designers with more names remaining to the top of the list
 *
 * @var [type]
 */
$designers = array(
    [ "Aaron Summers", "Aaron Summers", "Aaron Summers" ],
    [ "Adam Smart", "Adam Smart", "Adam Smart" ],
    [ "Andrew Montgomery", "Andrew Montgomery", "Andrew Montgomery" ],
    [ "Dave Robertson", "Dave Robertson", "Dave Robertson" ],
    [ "Holly Colby", "Holly Colby", "Holly Colby" ],
    [ "Karen Fok", "Karen Fok", "Karen Fok" ],
    [ "Kieran Lintott", "Kieran Lintott", "Kieran Lintott" ],
    [ "Rebecca Roffey", "Rebecca Roffey", "Rebecca Roffey" ],
    [ "Sonia Tam", "Sonia Tam", "Sonia Tam" ],
    [ "Steffi Wallace", "Steffi Wallace", "Steffi Wallace" ],
    [ "Taz Patel", "Taz Patel", "Taz Patel" ]
);
/**
 * Store the original designers to reset them once empty
 *
 * @var [type]
 */
$designers_bak = $designers;
/**
 * Generate an array of string dates between 2 dates
 *
 * @param string $start Start date
 * @param string $end End date
 * @param string $format Output format (Default: Y-m-d)
 *
 * @return array
 */
function getDatesFromRange( $start, $end ) {
    $array = array();
    $interval = new DateInterval('P1D');

    $realEnd = new DateTime($end);
    $realEnd->add($interval);

    $period = new DatePeriod(new DateTime($start), $interval, $realEnd);
    
    foreach($period as $date) { 
        $dayOfWeek = $date->format('l');
        if ( $dayOfWeek != 'Saturday' && $dayOfWeek != 'Sunday' ) {
            $array[] = $date->format('Y-m-d'); 
        }
    }

    return $array;
}
/**
 * Sort the array into sub-arrays that contain the most values
 * array(
 *     array('name', 'name', 'name')
 *     array('name', 'name')
 *     array('name')
 * )
 * https://stackoverflow.com/questions/7433569/php-sort-a-multidimensional-array-by-number-of-items#answer-7433753
 */
function sortByTotalItems($a, $b) {
    if ($a == $b) {
        return 0;
    }
    return (count($a) > count($b)) ? -1 : 1;
}
/**
 * Get the total amount of days in this week 1-5
 *
 * @var [type]
 */
$days_at_work = 3;
$total_days_in_week = 5;
$assigned_total = floor(count( $designers ) * $days_at_work / $total_days_in_week);    

/**
 * Each day
 *
 * @var [type]
 */
$working_weeks = array_chunk(getDatesFromRange('09-06-2021', '09-06-2022'), $total_days_in_week);
$given_designer = array();
foreach ( $working_weeks as $working_days ) {
    /**
     * Reset the designers
     *
     * @var [type]
     */
    foreach ( $working_days as $working_day ) {

        /**
         * Randomise the designers
         *
         * @var [type]
         */
        shuffle( $designers ); 
        /**
         * Sort the shuffle, so the sub-arrays count is descending
         * array(
         *     array('name', 'name', 'name')
         *     array('name', 'name')
         *     array('name')
         * )
         *
         * @var [$designers]
         */
        $designers = array_filter(array_map('array_filter', $designers));
        usort($designers, "sortByTotalItems");



        /**
         * Add designer to the working day
         *
         * @var [type]
         */

        $forcount = ( count($designers) < $assigned_total ) ? count($designers) : $assigned_total;



        for ($d=0; $d < $forcount; $d++) {
            /**
             * Add designer to the days visit
             *
             * @var [type]
             */

            $given_designer[] = array( 
                                    "title"=> $designers[$d][0],
                                    "start"=> $working_day
                                );
            /**
             * Remove the name from the names array -1 each loop
             *
             * @var [type]
             */
            array_pop($designers[$d]);
            /**
             * remove empty arrays so we can count the remaining designers
             * If there are less than 1 weeks worth of designers, reset the variable
             */
            $current_designers = array_filter(array_map('array_filter', $designers));
            if (  count($current_designers) < $assigned_total ) {
                $designers = $designers_bak;
            }
        }

        
    }  
}
?>

Below is what I'm left with after the loops and array_pop.

Let's call this array1

<?php 
array ( 0 => array ( ),
        1 => array ( ),
        2 => array ( ),
        3 => array ( ),
        4 => array ( 0 => 'Aaron Summers', ),
        5 => array ( 0 => 'Taz Patel', ),
        6 => array ( 0 => 'Sonia Tam', ),
        7 => array ( 0 => 'Adam Smart', ),
        8 => array ( 0 => 'Andrew Montgomery', ),
    ) 
?>

I then reset the array with the original values:

Let's call this array2

<?php
array ( 0 => array ( 0 => 'Aaron Summers', 1 => 'Aaron Summers', 2 => 'Aaron Summers', ),
        1 => array ( 0 => 'Adam Smart', 1 => 'Adam Smart', 2 => 'Adam Smart', ),
        2 => array ( 0 => 'Andrew Montgomery', 1 => 'Andrew Montgomery', 2 => 'Andrew Montgomery', ),
        3 => array ( 0 => 'Dave Robertson', 1 => 'Dave Robertson', 2 => 'Dave Robertson', ),
        4 => array ( 0 => 'Holly Colby', 1 => 'Holly Colby', ),
        5 => array ( 0 => 'Karen Fok', 1 => 'Karen Fok', 2 => 'Karen Fok', ),
        6 => array ( 0 => 'Kieran Lintott', 1 => 'Kieran Lintott', 2 => 'Kieran Lintott', ),
        7 => array ( 0 => 'Rebecca Roffey', 1 => 'Rebecca Roffey', 2 => 'Rebecca Roffey', ),
        8 => array ( 0 => 'Sonia Tam', 1 => 'Sonia Tam', 2 => 'Sonia Tam', ),
        9 => array ( 0 => 'Steffi Wallace', 1 => 'Steffi Wallace', 2 => 'Steffi Wallace', ),
        10 => array ( 0 => 'Taz Patel', 1 => 'Taz Patel', 2 => 'Taz Patel', ),
    )
?>

How would I be able to re-order the items in array2 based on the people left in array1 ?

array2 is the total size of the array and the array in its original form, before I have looped through and used array_pop() to remove the name.



source https://stackoverflow.com/questions/67909656/move-2nd-level-sub-array-to-the-top-of-the-1st-level-multidimentional-array-base

No comments:

Post a Comment