1

I have the following snippet of a large array:

Array
(
    [agreementTypes] => Array
        (
            [WS_PEAgreementType] => Array
                (
                    [0] => Array
                        (
                            [description] => Blah blah blah
                            [type] => Contract Supply
                        )

                    [1] => Array
                        (
                            [description] => Standard
                            [type] => Standard
                        )

                )

        )

Any key with "WS_PE" in it is redundant. Some are different to the above and in different levels of the array. I would like to find any key containing "WS_PE", take its values, and assign them directly to the parent of the found "WS_PE" key.

The above snippet needs to be so:

Array
    (
        [agreementTypes] => Array
            (
                [0] => Array
                    (
                        [description] => Blah blah blah
                        [type] => Contract Supply
                    )

                [1] => Array
                    (
                        [description] => Standard
                        [type] => Standard
                    )

            )

Finding the key is easy in a for loop. But I'm stuck knowing the name and level of the main array the parent of found key is (recursively).

EDIT: Here is a recursive function I have written. It works in terms of keeping track of the name of the parent key, but not the level/location in the array:

class PISupport {

    private $previousKey;

    public function stripRedundantAspireTags($rawData) {
        $returnArray = array();

        foreach($rawData as $key => $data) {

            if(false !== strpos($key, 'WS_PE')) {
                // Want to remove this key and assign data to the previous key
                $keyToUse = $this->previousKey;
            } else {
                // Just use the current key in the loop
                $keyToUse = $key;
            }

            $this->previousKey = $key;

            if(is_array($data)) {
                $obj[$keyToUse] = $this->stripRedundantAspireTags($data); //RECURSION
            } else {
                $obj[$keyToUse] = $data;
            }


        }

        return $returnArray;
    }
}

UPDATE

Almost working example thanks to didierc. The one issue is somehow it's discarding all elements but the first element of the first level of the array. Logic bug somewhere: https://gist.github.com/anonymous/b2fe834209ad74502824

6
  • You need to write a recursive function. Commented Jun 10, 2014 at 21:47
  • Are the WS_PE keys fixed? I mean are they always in the second level, or might be nested? If it's nested you need to write a recursive function Commented Jun 10, 2014 at 21:48
  • 1
    See stackoverflow.com/questions/20592046/… as a starting point. I don't have time right now to write a real answer. But you'll learn better if you figure it out yourself, use that as a hint. Commented Jun 10, 2014 at 21:49
  • Here's another question that applies: stackoverflow.com/questions/21938442/… Commented Jun 10, 2014 at 22:02
  • Where is the WS_PE located in the key name? is it always at the beginning? If not, how do you know which key it should be assigned to in the uppper array? Commented Jun 10, 2014 at 22:04

1 Answer 1

1

Here's my solution: it assumes the redundant key always start with the WS_PE prefix. It also supposes that there are no such key at the first level of the array.

function strip_boxing(&$parent, &$array){
  $keys = array();
  foreach($array as $key => $value){
    if (strpos($key, 'WS_PE') === 0) {
      $parent[substr($key,5,strlen($key) - 5)] = $value;
      array_push($keys, $key);
    }
    if (is_array($value)){
      strip_boxing($array, $value);
    }
  }
  foreach($keys as $k)
    unset($array[$k]);
}

A wrapper function will do the trick for the complete array:

function remove_ws_pe(&$data){
  $of = array();
  strip_boxing($of, $data);
  $data = array_merge($of, $data);
}

This code worked with the following value:

$a = array
  (
   'agreementTypes' => array
   (
    'WS_PEagreementTypes' => array 
    (
     '0' => array(
      'description' => 'Blah blah blah',
      'type' => 'Contract Supply'
      ),
     '1' => array(
      'description' => 'Standard',
      'type' => 'Standard'
      )
     )
    ));

If you turn it into a class, you could easily tune:

  • the key matching expression (strpos...)

  • and parent key selection (substr...). Be careful with overwriting though: if you have 2 entries or more in $array which contains the "WS_PE" pattern, how do you pick which parent key will be used?

Sign up to request clarification or add additional context in comments.

10 Comments

This is actually pretty clever with passing the parent array itself into the recursive call. Not sure how you would make the initial call though. You won't have a parent. I'm just trying a few things with your code now. Thank you.
Well, if you have these keys at the top level of the array, where would you put them anyway?
Sorry I mean I'm not sure how you would call strip_boxing() in the first place if there is no $parent. Just the original entire array. Still trying something with your code. I think this is definitely the right track.
it's in the answer now.
I've spent some time on this question; has been quite the brain cracker for me. In this strip_boxing function, I don't see any return. I think you somehow need to go in two levels or go recursively backwards but right now I can't think straight anymore. Good luck though.
|

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.