如果数组键包含字符串,则将值移动到父元素

时间:2014-06-10 21:44:45

标签: php arrays

我有一个大数组的以下片段:

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

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

                )

        )

" WS_PE"在它是多余的。有些与上面和阵列的不同级别不同。我想找到包含" WS_PE"的任何密钥,取其值,并将它们直接分配给找到的" WS_PE"键。

上面的代码片段必须如此:

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

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

            )

在for循环中查找键很容易。但我知道找到键的父元素的主数组的名称和级别是(递归地)。

编辑:这是我写的一个递归函数。它的工作原理是跟踪父键的名称,但不跟踪数组中的级别/位置:

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;
    }
}

更新

感谢didierc几乎成功的例子。一个问题是它以某种方式丢弃所有元素,但是丢弃了数组第一级的第一个元素。逻辑错误:https://gist.github.com/anonymous/b2fe834209ad74502824

1 个答案:

答案 0 :(得分:1)

这是我的解决方案:它假设冗余密钥始终以WS_PE前缀开头。它还假设在数组的第一级没有这样的键。

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]);
}

包装函数将完成整个数组的技巧:

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

此代码使用以下值:

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

如果你把它变成一个类,你可以很容易地调整:

  • 密钥匹配表达式(strpos ...)

  • 和父键选择(substr ...)。但要注意覆盖:如果$array中包含"WS_PE"模式的条目有2个或更多,那么如何选择使用哪个父密钥?