【问题标题】:If array key contains string, move values to parent element如果数组键包含字符串,则将值移动到父元素
【发布时间】:2014-06-10 21:44:44
【问题描述】:

我有一个大数组的以下sn-p:

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”键的父级。

上面的sn-p必须是这样的:

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

【问题讨论】:

  • 你需要写一个递归函数。
  • WS_PE 键是否已修复?我的意思是他们总是在第二层,或者可能是嵌套的?如果它是嵌套的,你需要编写一个递归函数
  • 请参阅stackoverflow.com/questions/20592046/… 作为起点。我现在没有时间写一个真正的答案。但是如果你自己弄清楚,你会学得更好,以此作为提示。
  • 这是另一个适用的问题:stackoverflow.com/questions/21938442/…
  • 键名中的WS_PE 在哪里?它总是在开始吗?如果不是,你怎么知道它应该分配到上数组中的哪个键?

标签: php arrays


【解决方案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...)。不过要小心覆盖:如果您在包含 "WS_PE" 模式的 $array 中有 2 个或更多条目,您如何选择将使用哪个父键?

【讨论】:

  • 这实际上非常聪明,将父数组本身传递给递归调用。不过,不确定您将如何拨打初始电话。你不会有父母的。我现在只是用你的代码尝试一些事情。谢谢。
  • 好吧,如果你在数组的顶层有这些键,你会把它们放在哪里?
  • 对不起,如果没有 $parent,我不确定你会如何调用 strip_boxing()。只是原始的整个数组。仍在尝试使用您的代码。我认为这绝对是正确的轨道。
  • 它现在在答案中。
  • 我在这个问题上花了一些时间;对我来说简直是脑筋急转弯。在这个 strip_boxing 函数中,我看不到任何回报。我认为您需要以某种方式进入两个级别或递归地倒退,但现在我无法再思考了。不过祝你好运。
猜你喜欢
  • 2016-04-09
  • 2018-05-05
  • 1970-01-01
  • 2018-04-02
  • 2020-02-14
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多