简体   繁体   中英

Create multidimensional sub array from existing array values

I've been racking my head on this one and am hoping someone has a creative solution for this. In short, we are pulling info from a database and would like to create a nested array using some of the result columns, sorted and grouped by their values;

A result may look something like this, where it is always an array of single-level arrays:

Array (
    [0] => Array (
        ['day'] => 'a',
        ['stuff'] => 'b',
        ['nested3'] => 'c',
        ['data1'] => 'park',
        ['data2'] => 'sunny'
    ),
    [1] => Array (
        ['day'] => 'a',
        ['stuff'] => 'b',
        ['nested3'] => 'c',
        ['data1'] => 'store',
        ['data2'] => 'sunny'
    ),
    [2] => Array (
        ['day'] => 'a',
        ['stuff'] => 'z',
        ['nested3'] => 'c',
        ['data1'] => 'home',
        ['data2'] => 'rainy'
    ),
)

Here, I'd like to create a new nested array, grouped X levels deep dictated by the number of 'nested' named type columns. Note here that 'nested' naming scheme is only for example, the actual column name could be anything AND could be 3 columns deep to sort by, or more or less - so hard coding the sorting loops is not an option.

Array (
    'a' => Array (
        'b' => Array ( 
            'c' => Array (
                [0] => Array (
                    'data1' => 'park',
                    'data2' => 'sunny'
                ),
                [1] => Array (
                    'data1' => 'store',
                    'data2' => 'sunny'
                )
            )
        ),
        'z' => Array (
            'c' => Array (
                'data1' => 'home',
                'data2' => 'rainy'
            )
        )
    )
)

This will be used to generate tree style html tables. Unfortunately, it does not appear that PDO's fetch supports grouping by more than one columns so I need cook up my own.

You will notice the data is originally associative - since Im pulling it from PDO it can be numerically indexed as well, this part doesnt matter as I will know ahead of time what order the data is in.

I will know ahead of time how many columns deep the nesting columns will go, so something like this would work:

function nest_sort(&arr, $sort_col_count) {
    ...
}

or a function I can just specify the names of the columns to use for sorting, in order of nesting

function nest_sort(&arr, $sort_columns) // Sorts $arr by $sort_columns values // in nesting order of $sort_columns } nest_sort($array, array('nested1', 'nested2'))

Its possible to be working with decently large data sets, 1000s of rows of data. So resources are of concern.

Ive made many attempts at this and my largest hangup is the fact that the sort depth is not hard-predictable, and writing a recursive function to create nested arrays from its self has been a PITA.

I can't help but think there is an easier and more performant way to accomplish this using array_walk_recursive and/or array_merge recursive.

Appreciate it everyone.

Well, I finally have a functioning piece together after more testing. Now ill just have to finish the table generation. It will pass by reference the array to be sorting as to free the memory as it goes.

$a[] = array('one', 'two', 'three', 'win', 'ner');
$a[] = array('one', 'two', 'three', 'win', 'dog');
$a[] = array('one', 'two', 'three', 'lost', 'cat');
$a[] = array('one', 'two', 'five', 'win', 'ner');
$a[] = array('one', 'two', 'five', 'lost', 'ner');

function dep(&$a, $depth) {

    $count = count($a);
    for($z = 0; $z < $count; $z++) {
        unset($tmp);
        $ptr = &$tmp;

        for($x = 0; $x <= $depth; $x++) {   
            $old = $new; 
            $new = array_shift($a[$z]);
            if($x == 0) continue;

            $ptr = &$ptr[$old];
            if($x == $depth) {
                array_unshift($a[$z], $new);
                $ptr['stats'][] = $a[$z];
            }
        }
        $array = array_merge_recursive((array)$array, $tmp);
        unset($a[$z]);
    }
    return $array;
}

Sample result..

Array
(
    [one] => Array
        (
            [two] => Array
                (
                    [three] => Array
                        (
                            [stats] => Array
                                (
                                    [0] => Array
                                        (
                                            [0] => win
                                            [1] => ner
                                        )

                                    [1] => Array
                                        (
                                            [0] => win
                                            [1] => dog
                                        )

                                    [2] => Array
                                        (
                                            [0] => lost
                                            [1] => cat
                                        )

                                )

                        )

                    [five] => Array
                        (
                            [stats] => Array
                                (
                                    [0] => Array
                                        (
                                            [0] => win
                                            [1] => ner
                                        )

                                    [1] => Array
                                        (
                                            [0] => lost
                                            [1] => ner
                                        )

                                )

                        )

                )

        )

)

This way each array level above the stats key will be used as a title 'branch' in the tree-table style tables this will be used to generate.

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