如何在php中的多个Level数组上运行递归函数

时间:2018-02-21 07:26:44

标签: php arrays

我有两个数组,一个是$apiRes,第二个是$mappData我希望匹配 mappData 数组中存在的字段,并指定 apiRes 的值匹配领域。

注意:api的响应可能有所不同,mapdata数组会根据api响应而改变我的两个数组和输出格式:

<?php
 $apiRes = [ 
 [
   'firstname' => 'first name des',
   'title' => "title des",
   'category' => 1,
   'result' => 
     [
      0 => [
          'name' => 'Masterpass',
           'skill' => 'low level one'
         ],
      1 => [
          'name' => 'Visa',
          'skill' => 'low level two'
      ],
      2 => [
        'name' => 'Pocketpos',
        'skill' => 'low level three'
    ],   
    ],
   'list' => [
       'product_name'=>'product name',
        'amount' => [
            'currency'=>'$',
            'kind'   => 'kind'
        ]
   ],  
   'priority' => 'Low',
   'visible_to' => 'Everyone',
  ]
];
 $mappData  =  [
    0 =>  [
      "src_field" => "firstname",
      "target_field" => "new1519110449758",
      "src_field_data_type" => "string"
    ],
    1 => [
      "src_field" => "result.name",
      "target_field" => "new1519110811942",
      "src_field_data_type" => "string"
    ],
    2 =>  [
      "src_field" => "list.product_name",
      "target_field" => "new1519110451708",
      "src_field_data_type" => "string"
    ],
    3 =>  [
      "src_field" => "list.amount.currency",
      "target_field" => "new1517556165360",
      "src_field_data_type" => "string"
    ]

    ]; 

我的最终输出应为:

$output = [
  "new1519110449758" => "first name des",
  "new1519110451708" => "product name",
  "new1517556165360" => "$",
  "new1519110811942" =>  [
    0 => "Masterpass",
    1 => "Visa",
    2 => "Pocketpos"

  ]
];

请帮忙 谢谢

1 个答案:

答案 0 :(得分:0)

我已经稍微改变了你的mappData,因为它很难知道如何处理result.name元素,因为它重复了。我所做的就是更改它以便它*result.name,并使用其中*表示存在多个值的事实。

我试图用足够的方法来解释每一位代码,主要原则是使用递归例程一次一步地遍历数组的每个级别。

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);

$apiRes = [
    [
        'firstname' => 'first name des',
        'title' => "title des",
        'category' => 1,
        'result' =>
        [
            0 => [
                'name' => 'Masterpass',
                'skill' => 'low level one'
            ],
            1 => [
                'name' => 'Visa',
                'skill' => 'low level two'
            ],
            2 => [
                'name' => 'Pocketpos',
                'skill' => 'low level three'
            ],
        ],
        'list' => [
            'product_name'=>'product name',
            'amount' => [
                'currency'=>'$',
                'kind'   => 'kind'
            ]
        ],
        'priority' => 'Low',
        'visible_to' => 'Everyone',
    ]
];
$mappData  =  [
    0 =>  [
        "src_field" => "firstname",
        "target_field" => "new1519110449758",
        "src_field_data_type" => "string"
    ]
    ,
    1 => [
        "src_field" => "*result.name",
        "target_field" => "new1519110811942",
        "src_field_data_type" => "string"
    ],
    2 =>  [
        "src_field" => "list.product_name",
        "target_field" => "new1519110451708",
        "src_field_data_type" => "string"
    ],
    3 =>  [
        "src_field" => "list.amount.currency",
        "target_field" => "new1517556165360",
        "src_field_data_type" => "string"
    ]

];

$result = [];

// Process next element of the array
function getArrayElement ( $next, $data, $array = false )   {
    // Extract key for this level
    $key = array_shift($next);
    // If starts with * then this means there are multiple of them
    if ( $key[0] == "*" ){
        $nextArray = true;
        // remove from current key
        $key = substr($key,1);
    }
    else    {
        $nextArray = false;
    }

    if ( $array ){
        $res = [];
        // extract the data from each element at this level
        foreach ( $data as $read )  {
            $res[] = $read[$key];
        }
        $data = $res;
    }
    else    {
        // Fetch the element for the key for this level
        $data = $data [ $key ];
    }
    // If there are more levels to deal with then repeat this method
    if ( count($next) > 0 ) {
        $data =  getArrayElement ( $next, $data, $nextArray );
    }
    return $data;
}

// Flatten out original array if necessary
if ( count($apiRes) == 1 ){
    $apiRes = $apiRes[0];
}
// Process each part of lookup
foreach ( $mappData as $element )   {
    // Create an array of the elments broken down into each level
    $map = explode( '.', $element['src_field']);
    $result[$element['target_field']] = getArrayElement($map, $apiRes);
}

print_r($result);