简体   繁体   中英

How to Filter multidimensional array and create a new array

I have this kind of array, based on Page ID like: 32,143.

I want to search if array key position have both value in it, then ignore prepend and append value and consider ONLY both value.

And if the array has NO both value and multiple prepend and append value, then it will consider based on priority key.

$sort_result = Array
(
    [32] => Array
        (
            [0] => Array
                (
                    [page] => 32
                    [position] => append
                    [priority] => 1
                )

            [1] => Array
                (
                    [page] => 32
                    [position] => append
                    [priority] => 2
                )

            [2] => Array
                (
                    [page] => 32
                    [position] => prepend
                    [priority] => 3
                )

            [3] => Array
                (
                    [page] => 32
                    [position] => both
                    [priority] => 3
                )

            [4] => Array
                (
                    [page] => 32
                    [position] => prepend
                    [priority] => 4
                )

        )

    [143] => Array
        (
            [0] => Array
                (
                    [page] => 143
                    [position] => prepend
                    [priority] => 19
                )
            [1] => Array
                (
                    [page] => 143
                    [position] => prepend
                    [priority] => 18
                )
            [2] => Array
                (
                    [page] => 143
                    [position] => append
                    [priority] => 18
                )

        )

)

I tried the following code, but not working:

<?php 
foreach ( $modify_array as $key => $value ) {
    foreach( $value as $k1 => $v1) {
        if ( array_search( "both", $v1 ) ) {
            $final_array[$key][$k1] = $v1;
        } else{
            if ( array_search( "prepend", $v1 ) ) {
                $final_array[$key][$k1] = $v1;
            }
            if ( array_search( "append", $v1 ) ) {
                $final_array[$key][$k1] = $v1;
            }
           
        }
     break;
    }
}

I am expecting output like this:

Array
(
    [32] => Array
        (
            
            [3] => Array
                (
                    [page] => 32
                    [position] => both
                    [priority] => 3
                )

        )

    [143] => Array
        (
            [1] => Array
                (
                    [page] => 143
                    [position] => prepend
                    [priority] => 18
                )
            [2] => Array
                (
                    [page] => 143
                    [position] => append
                    [priority] => 18
                )

        )

)

EDIT 1:

I manage to work, using this code

$modify_array = array();
foreach ( $sort_result as $sort_result_key => $sort_result_value ) {  
    $modify_array[$sort_result_value['page']][] = $sort_result_value;
}

foreach ( $modify_array as $key => $value ) {

    $filter_array[$key]['both_yes'] = array_keys(array_column($value, 'position'),'both');
    $filter_array[$key]['prepend_yes'] = array_keys( array_column($value, 'position'),'prepend');
    $filter_array[$key]['append_yes'] = array_keys(array_column($value, 'position'),'append');

} 
    

foreach ( $filter_array as $filter_array_key => $filter_array_value ) {
    if ( ! empty( $filter_array_value['both_yes'])) {
        $a = $filter_array_value['both_yes'][0];
        $final_array[] = $modify_array[$filter_array_key][$a];
        
    } else {
        if ( ! empty( $filter_array_value['prepend_yes'])) {
            $b = $filter_array_value['prepend_yes'][0];
            $final_array[] = $modify_array[$filter_array_key][$b];
        }
        if ( ! empty( $filter_array_value['append_yes'])) {
            $c = $filter_array_value['append_yes'][0];
            $final_array[] = $modify_array[$filter_array_key][$c];
        }
    }
}

Edit 2: var_export

 array ( 32 => array ( 0 => array ( 'page' => '32', 'position' => 'append', 'priority' => '1', ), 1 => array ( 'page' => '32', 'position' => 'append', 'priority' => '2', ), 2 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '3', ), 3 => array ( 'page' => '32', 'position' => 'both', 'priority' => '3', ), 4 => array ( 'page' => '32', 'position' => 'prepend', 'priority' => '4', ), ), 143 => array ( 0 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '18', ), 1 => array ( 'page' => '143', 'position' => 'append', 'priority' => '18', ), 2 => array ( 'page' => '143', 'position' => 'prepend', 'priority' => '19', ), ), )

I think the lowest time complexity that I can boil this task down to uses 1 full loop of your input array followed by a loop of the grouped data with a nested loop to isolate the rows with the lowest priority value.

The first loop does the grouping and potentially sheds worthless non-both rows for a trivial memory savings.

The second loop iterates the page groups, then the inner loop favors both rows and only uses non-both rows if there are no both rows. The if and elseif ensure that only the rows with the lowest priority number are retained. I added a rsort() call with the assumption that you want prepend rows before append rows. If the position values don't need to be prioritized, then omit the condition block containing the rsort() call.

Code: ( Demo )

$array = [
    ['page' => '32', 'position' => 'append', 'priority' => '1'],
    ['page' => '32', 'position' => 'append', 'priority' => '2'],
    ['page' => '32', 'position' => 'prepend', 'priority' => '3'],
    ['page' => '32', 'position' => 'both', 'priority' => '3'],
    ['page' => '32', 'position' => 'prepend', 'priority' => '4'],
    ['page' => '143', 'position' => 'prepend', 'priority' => '18'],
    ['page' => '143', 'position' => 'append', 'priority' => '18'],
    ['page' => '143', 'position' => 'prepend', 'priority' => '19'],
];

$result = [];
foreach ($array as $row) {
    if (!isset($result[$row['page']])) {
        $result[$row['page']] = ['both' => [], 'non-both' => []];
    }
    if ($row['position'] !== 'both') {
        if ($result[$row['page']]['both']) {
            continue; // nothing worth doing in this case, ignore the row
        } else {
            $result[$row['page']]['non-both'][] = $row;
        }
    } else {
        $result[$row['page']]['both'][] = $row;
    }
}

foreach ($result as $page => $rows) {
    $keep = [];
    foreach ($rows['both'] ?: $rows['non-both'] as $row) {
        if (!$keep || $row['priority'] < $keep[0]['priority']) {
            $keep = [$row];
        } elseif ($row['priority'] === $keep[0]['priority']) {
            $keep[] = $row;
        }
    }
    if ($keep[0]['position'] !== 'both') {
        rsort($keep);  // assuming you need prepend to occur before append
    }
    $result[$page] = $keep;
}
var_export($result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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