0

I have to remove an internal array from an array. Actually, the array is obtained by decoding JSON, and can go upto n levels. I need to remove an internal array from an array of its parent based on the key which is dynamic. Below is the code that I have tried referring to answers on php arrays.

$quotationHistory = json_decode($quotationCollection->getHistory(), true);
$quotationId = 5;
foreach ($quotationHistory as $sales_id => $history) {
    foreach($history as $quotationIdValue => $values) {
        if ($quotationId == $quotationIdValue) {
            unset ($history[$quotationIdValue]);
        }
    }
}

sample:

Array
(
    [1] => Array
        (
            [5] => Array
                (
                    [0] => Array
                        (
                            [0] => 3
                            [1] => 8490.0000
                            [2] => 21-10-2016 11:43:18am
                            [3] => 24-11-2016 11:43:18am
                            [4] => 199
                            [5] => rtg
                        )

                    [1] => Array
                        (
                            [0] => 12
                            [1] => 8490.0000
                            [2] => 21-10-2016 11:43:40am
                            [3] => 24-11-2016 11:43:18am
                            [4] => 199
                            [5] => rtg
                        )

                    [2] => Array
                        (
                            [0] => 45
                            [1] => 8490.0000
                            [2] => 21-10-2016 11:43:54am
                            [3] => 24-11-2016 11:43:18am
                            [4] => 199
                            [5] => rtg
                        )

                    [3] => Array
                        (
                            [0] => 11
                            [1] => 8490.0000
                            [2] => 21-10-2016 11:44:04am
                            [3] => 24-11-2016 11:43:18am
                            [4] => 199
                            [5] => rtg
                        )

                    [4] => Array
                        (
                            [0] => 54
                            [1] => 8490.0000
                            [2] => 21-10-2016 11:44:16am
                            [3] => 24-11-2016 11:43:18am
                            [4] => 199
                            [5] => rtg
                        )

                )

        )

)

Now, I want to remove the second level data with key = 5

2
  • Are you sure you passed in the if condition ? Is your $quotationId variable correctly initialized? Do a dump of your $quotationId and your array. Add a trace in the if condition. Commented Oct 21, 2016 at 7:26
  • Please format correctly the "sample" you just added, it's unreadable. Commented Oct 21, 2016 at 7:29

2 Answers 2

1

You'd better do the unset on the original array:

$quotationHistory = json_decode($quotationCollection->getHistory(), true);            
foreach($quotationHistory as $sales_id => $history) {
    foreach($history as $quotationIdValue => $values) {
        if($quotationId == $quotationIdValue){
            unset($quotationHistory[$sales_id][$quotationIdValue]);
        }
    }
}

The reason is that the internal array is passed as a copy. But you can also specify an assignation by reference:

In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference (official Php doc).

$quotationHistory = json_decode($quotationCollection->getHistory(), true);            
foreach($quotationHistory as $sales_id => &$history) {
    foreach($history as $quotationIdValue => &$values) {
        if($quotationId == $quotationIdValue){
            unset($$history[$quotationIdValue]);
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

The item is not getting removed.
Are you sure you passed in the if condition ? Is your $quotationId variable correctly initialized? Do a dump of your $quotationId and your array. Add a trace in the if condition.
I have added a sample array in my question
0

You will probably want a recursive iterator since the return can be any level down in the array (presumably that's what you mean by n levels). One note, it would remove any key with the same value so it would remove any key with 5. You would be better to recurse to remove the key based on value rtg:

$arr    =   array(
    'one'=>array(
        'one'=>'and a half',
        'two'=>array(
            'three'=>'three and a half'
        )
    )
);

function recurse($array,$remove=false)
    {
        foreach($array as $key => $value) {
            if($key != $remove){
                if(is_array($value)) {
                    $new[$key]  =   recurse($value,$remove);
                }
                else
                    $new[$key]  =   $value;
            }
        }

        return $new;
    }

# Run the iterator to remove the key named "three"
print_r(recurse($arr,'three'));

If you need to search by value, this should work:

function recurseValue($array,$remove=false)
    {
        foreach($array as $key => $value) {
            if(is_array($value)) {
                $new[$key]  =   recurseValue($value,$remove);
            }
            else {
                if($value != $remove){
                    $new[$key]  =   $value;
                }
            }
        }

        return $new;
    }
# Run the iterator to remove the key with the value named "Three and a half"
print_r(recurseValue($arr,'three and a half'));

Gives you:

Array
(
    [one] => Array
        (
            [one] => and a half
            [two] => 
        )

)

This last option will normalize the array to one level so you can loop over it normally:

function recurseArray($array,&$new,$bkey = false)
    {
        foreach($array as $key => $value) {
            if(is_array($value)) {
                recurseArray($value,$new,$key);
            }
            else {
                $new[$bkey][]   =   $value;
            }
        }
    }

$new = array();
recurseArray($arr,$new);
print_r($new);

Gives you:

Array
(
    [0] => Array
        (
            [0] => 3
            [1] => 8490.0000
            [2] => 21-10-2016 11:43:18am
            [3] => 24-11-2016 11:43:18am
            [4] => 199
            [5] => rtg
        )

    [1] => Array
        (
            [0] => 3
            [1] => 8490.0000
            [2] => 21-10-2016 11:43:18am
            [3] => 24-11-2016 11:43:18am
            [4] => 199
            [5] => rtg
        )

    [2] => Array
        (
            [0] => 3
            [1] => 8490.0000
            [2] => 21-10-2016 11:43:18am
            [3] => 24-11-2016 11:43:18am
            [4] => 199
            [5] => rtg
        )

    [3] => Array
        (
            [0] => 3
            [1] => 8490.0000
            [2] => 21-10-2016 11:43:18am
            [3] => 24-11-2016 11:43:18am
            [4] => 199
            [5] => rtg
        )
)

6 Comments

I want to remove the value based on key = 5
Can it be at depth?
No, it is on the second level as it is in the sample. The depth n is for some sensitive data, if available.
Oh, then just do a double loop then as noted in the other answer. Recursing is only if you don't know what depth the target array is at.
I did one last one, if you are interested. It will flatten the array to one level so you only have to do one foreach on the $new array in my example. It's probably a bit overkill, but it might give you some ideas.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.