John
John

Reputation: 206

How to get Array data by key value from multidimensional array?

I have a multidimensional array in my php variable like,

Array
(
    [type] => salesrule/rule_condition_combine
    [attribute] => 
    [operator] => 
    [value] => 1
    [is_value_processed] => 
    [aggregator] => any
    [conditions] => Array
        (
            [0] => Array
                (
                    [type] => salesrule/rule_condition_combine
                    [attribute] => 
                    [operator] => 
                    [value] => 1
                    [is_value_processed] => 
                    [aggregator] => all
                    [conditions] => Array
                        (
                            [0] => Array
                                (
                                    [type] => salesrule/rule_condition_address
                                    [attribute] => postcode
                                    [operator] => >
                                    [value] => 00999
                                    [is_value_processed] => 
                                )

                            [1] => Array
                                (
                                    [type] => salesrule/rule_condition_address
                                    [attribute] => postcode
                                    [operator] => <
                                    [value] => 96200
                                    [is_value_processed] => 
                                )
                        )
                )
            [1] => Array
                (
                    [type] => salesrule/rule_condition_combine
                    [attribute] => 
                    [operator] => 
                    [value] => 1
                    [is_value_processed] => 
                    [aggregator] => all
                    [conditions] => Array
                        (
                            [0] => Array
                                (
                                    [type] => salesrule/rule_condition_address
                                    [attribute] => postcode
                                    [operator] => >=
                                    [value] => 97000
                                    [is_value_processed] => 
                                )

                            [1] => Array
                                (
                                    [type] => salesrule/rule_condition_address
                                    [attribute] => postcode
                                    [operator] => <
                                    [value] => 99500
                                    [is_value_processed] => 
                                )
                        )
                )
        )
)

Here, the length of the array can very. Now I want to get only postcode values from my array like,

Array(
     [0]=>Array
          ( 
             [0] => Array
                 (
                    [attribute] => postcode
                    [operator] => >
                    [value] => 00999
                  )
             [1] => Array
                 (
                    [attribute] => postcode
                    [operator] => <
                    [value] => 96200
                  )
          )
     [1]=>Array
          ( 
             [0] => Array
                 (
                    [attribute] => postcode
                    [operator] => >=
                    [value] => 97000
                  )
             [1] => Array
                 (
                    [attribute] => postcode
                    [operator] => <
                    [value] => 99500
                  )
          )
    )

I have user multiple loops and conditions to do it.

foreach( $conditions['conditions'] as $_conditions ):
    foreach( $_conditions['conditions'] as $_condition ):
        $counter++;
        $loopCounter++; 
        foreach($_condition['conditions'] as $condition ):
            if($condition['attribute'] == 'postcode'){ $postcodes[$counter][$condition['operator']] = $condition['value']; }
            $loopCounter++;
        endforeach;
    endforeach;
endforeach;

This works, but I think that is not a proper way to do it. I also tried to use array_map() and array_column() and some other ways but they only works if we have one level of sub arrays. Basically I just want to get postcode data from this array without using multilevel loop. Any help is greatly appreciated.

Upvotes: 0

Views: 90

Answers (1)

Ryan Vincent
Ryan Vincent

Reputation: 4513

Required: Extract certain leaf nodes identified as 'postcode' from a tree held as an array.

There is one issue:

1) The input array 'root' is an associated array (the 'condition') rather than an array of 'conditions' like the rest of the tree. This explains why I used the array($sourceData) rather than $sourceData, to start the processing.

Demonstration at evel.in Source code at Pastebin.com

The function that scans the array

/**
 * function recurse the array looking for post codes...
 *
 * @param array $conditions
 * @param array $postcodes by reference
 * @return void
 */
function getPostcodes($conditions, &$postcodes) {

    $currentPostcodes = array();

    foreach ($conditions as $condition) {

        if (!empty($condition['conditions'])) { // recurse...
           getPostcodes($condition['conditions'], $postcodes);
           continue; // process next entry...
        }

        // extract the postcodes...  
        if (   isset($condition['attribute'])
             && $condition['attribute']  === 'postcode') {
            $currentPostcodes[] = $condition;
        }
    }

    if (!empty($currentPostcodes)) {
        $postcodes[] = $currentPostcodes;
    }
    return;
}

Run it:

// output in here
$postcodes = array();

// note: input needs to be an array that looks like a `condition_combine`

getPostcodes(array($a),  $postcodes);

echo 'output start', PHP_EOL;
print_r($postcodes);
echo 'output end', PHP_EOL;
exit;

The output:

output start
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [type] => salesrule/rule_condition_address
                    [attribute] => postcode
                    [id] => lvl__2--0
                    [operator] => >
                    [value] => 00999
                    [is_value_processed] => 
                )

            [1] => Array
                (
                    [type] => salesrule/rule_condition_address
                    [attribute] => postcode
                    [id] => lvl__2--1
                    [operator] => <
                    [value] => 96200
                    [is_value_processed] => 
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [type] => salesrule/rule_condition_address
                    [attribute] => postcode
                    [operator] => >=
                    [id] => lvl__2--3
                    [value] => 97000
                    [is_value_processed] => 
                )

            [1] => Array
                (
                    [type] => salesrule/rule_condition_address
                    [attribute] => postcode
                    [id] => lvl__2--4
                    [operator] => <
                    [value] => 99500
                    [is_value_processed] => 
                )
        )
)
output end

Upvotes: 1

Related Questions