递归迭代多维数组,并返回相同的数组结构,并在PHP中插入新的键/值 [英] Iterate multidimensional Array recursively and return same array structure and inserting new key/values in PHP

查看:116
本文介绍了递归迭代多维数组,并返回相同的数组结构,并在PHP中插入新的键/值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个片段,该片段采用多维数组,并在找到命名搜索键的同一级别插入一些键。
我不必依赖数组的结构(但最多为5个级别)
我不能使用按引用传递,因此传统的循环函数对这种方法无济于事。



我有2种选择:SPL或递归,它可以重新构造数组并沿途进行更改



使用SPL,我似乎无法插入新值。

  $ a = new \ArrayObject($ priceConfig ); 
$ array = new \RecursiveArrayIterator($ a);
$ iterator = new \RecursiveIteratorIterator($ array,\RecursiveIteratorIterator :: SELF_FIRST);
foreach($ iterator as $ key => gt; $ value){
if(is_array($ value)&& $ key =='prices'){
$ iterator-> ; offsetSet('myPrice',['amount'=>'1.00']));
}
}

print_r($ a-> getArrayCopy());

它不会以所需的级别插入新键,但会在数组中循环。我想念的是什么?



用于重构数组并在嵌套数组的键搜索中插入新值的递归函数有效,但是我想使用Iterators

 函数递归($ input,$ searchKey,$ key = null){
$ holder = array();
if(is_array($ input)){
foreach($ input as $ key => $ el){
if(is_array($ el)){
$ holder [$ key] =递归($ el,$ searchKey,$ key);
if($ key == $ searchKey){
$ holder [$ key] [’inertedPrice’] = value;
}
} else {
$ holder [$ key] = $ el;
}
}
}
返回$ holder;
}

输入(将始终具有 X级价格键和价格结构)

  [1] =>数组

[1] =>数组

[prices] =>数组

[onePrice] => Array( [amount] => 10)
[finalPrice] =>数组([amount] => 10)

[key1] => value2
[key2] ] => value2


[2] =>数组

[价格] = >>数组

[otherPrice] => Array([amount] => 20)
[finalPrice] => Array([amount] => 20)

[key] => ; value



输出

  [1] =>数组

[1] =>数组

[prices] =>数组

[onePrice] => Array( [金额] => 10)
[最终价格] =>数组([金额] => 10)
[INSERTEDPrice] =>数组([金额] =>值)

[key1] => value2
[key2] => value2


[2] =>数组

[价格] =>数组

[otherPrice] => Array([amount] => 20)
[finalPrice] => Array([amount ] => 20)
[INSERTEDPrice] => Array([amount] =>)

[key] => value value


解决方案

您可以使用诸如foreach循环和递归之类的基本工具轻松解决此问题。

  function mergeWithKey($ targetKey,$ new,array $ array){
foreach( $ array as $ key => $ value){
if($ key === $ targetKey){
$ array [$ key] = array_merge($ array [$ key],$ new) ;
}
elseif(is_array($ value)){
$ array [$ key] = mergeWithKey($ targetKey,$ new,$ value);
}
}
返回$ array;
}

//示例
$ output = mergeWithKey(’prices’,array(’INSERTEDPrice’=>’value’),$ input);

简单来说,如果找到要查找的键,我们就会遍历数组,然后合并在新的价格。如果我们改为找到一个子数组,则将新价格合并到该子数组中。



我通过保持键价格做了一些努力来概括该功能。作为参数。



使用几种常见算法,您可以很好地鞭打此功能,而好处是,您可以重复使用这些算法。 。一种是将键和值都映射到数组,另一种是将2D数组展平为1D数组。

 函数arrayMapWithKey(callable $ f,array $ array){
$ out = array();
foreach($ array as $ key => $ value){
$ out [$ key] = $ f($ key,$ value);
}
返回$ out;
}

函数concat(array $ array){
if(empty($ array)){
return array();
}
else {
return call_user_func_array(’array_merge’,$ array);
}
}

这些定义使您可以编写替代解决方案。 / p>

  function addPrice($ name,$ price,$ data){
return concat(arrayMapWithKey(
function ($ k,$ v)使用($ name,$ price){
if($ k ==='prices'){
return array($ k => array_merge($ v,array ($ name => $ price)));
}
elseif(is_array($ v)){
return array($ k => addPrice($ name,$ price, $ v));
}
else {
return array($ k => $ v);
}
},
$ data
));
}

arrayMapWithKey 而是复制带有值的键,然后使用常规的 array_map

  function arrayWithKeys(array $ array){
$ out = array();
foreach($ array as $ key => gt; $ value){
//在PHP数组中通常用作元组,
//在这里有2个元组。
$ out [] = array($ key,$ value);
}
返回$ out;
}


I am trying to write a snippet that takes an multidimensional array and inserts some keys at the same level where a named search key is found. I don't have to rely on the structure of the array (but will be at most 5 levels) I can't use passing by reference so a traditional recurring function won't help with that approach.

I have 2 options: SPL or a recursion that re-constructs the array and alters it along the way

with SPL I can't seem to Insert a new value..

            $a= new \ArrayObject($priceConfig);
            $array = new \RecursiveArrayIterator($a);
            $iterator = new \RecursiveIteratorIterator($array, \RecursiveIteratorIterator::SELF_FIRST);
            foreach ($iterator as $key => $value) {
                if (is_array($value) && $key == 'prices') {
                    $iterator->offsetSet('myPrice',['amount'=>'1.00']);
                }
            }

            print_r($a->getArrayCopy());

It won't insert the new key at the desired level but it does loop through the array.. what am I missing?

The recursive function that reconstructs the array and insert new values at my key search in the nested array works, but I would like to use the Iterators to do that..

             function recursive( $input, $searchKey, $key=null) {
                $holder = array();
                if(is_array( $input)) {
                    foreach( $input as $key => $el) {
                        if (is_array($el)) {
                            $holder[$key] = recursive($el, $searchKey, $key);
                            if ($key == $searchKey) {
                                $holder[$key]['inertedPrice'] = "value";
                            }
                        } else {
                            $holder[$key] = $el;
                        }
                    }
                }
                return $holder;
            }

INPUT (will always have some "prices key and structure at X level")

    [1] => Array
        (
            [1] => Array
                (
                    [prices] => Array
                        (
                            [onePrice] => Array( [amount] => 10)
                            [finalPrice] => Array ([amount] => 10)
                        )
                    [key1] => value2
                    [key2] => value2
                )

            [2] => Array
                (
                    [prices] => Array
                        (
                            [otherPrice] => Array([amount] => 20)
                            [finalPrice] => Array([amount] => 20)
                        )
                    [key] => value
                )
        )
)

Output

[1] => Array
    (
        [1] => Array
            (
                [prices] => Array
                    (
                        [onePrice] => Array( [amount] => 10)
                        [finalPrice] => Array ([amount] => 10)
                        [INSERTEDPrice] => Array([amount] => value)
                    )
                [key1] => value2
                [key2] => value2
            )

        [2] => Array
            (
                [prices] => Array
                    (
                        [otherPrice] => Array([amount] => 20)
                        [finalPrice] => Array([amount] => 20)
                        [INSERTEDPrice] => Array([amount] => )
                    )
                [key] => value
            )
    )

)

解决方案

You could approach the problem using basic tools like foreach loops and recursion fairly easily. Here is such a solution.

function mergeWithKey($targetKey, $new, array $array) {
  foreach ($array as $key => $value) {
    if ($key === $targetKey) {
      $array[$key] = array_merge($array[$key], $new);
    }
    elseif (is_array($value)) {
      $array[$key] = mergeWithKey($targetKey, $new, $value); 
    }
  }
  return $array;
}

// Example
$output = mergeWithKey('prices', array('INSERTEDPrice' => 'value'), $input);

Simply, as we iterate over the array if we find the key we're looking for then we merge in the new price. If we instead find a sub-array then we merge the new price into that sub-array.

I gave some effort to generalise the function by keeping the key "prices" as a parameter. This is probably still a wonky function unlikely to see reuse.

With a couple common algorithms you can whip up this function quite nicely, and the bonus is you can reuse the algorithms. One is to map the array with both key and value, and the other is to flatten a 2D array to a 1D array.

function arrayMapWithKey(callable $f, array $array) {
  $out = array();
  foreach ($array as $key => $value) {
    $out[$key] = $f($key, $value);
  }
  return $out;
}

function concat(array $array) {
  if (empty($array)) {
    return array(); 
  }
  else {
    return call_user_func_array('array_merge', $array);
  }
}

These definitions enable to you write an alternative solution.

function addPrice($name, $price, $data) {
  return concat(arrayMapWithKey(
    function ($k, $v) use ($name, $price) {
      if ($k === 'prices') {
        return array($k => array_merge($v, array($name => $price)));
      }
      elseif (is_array($v)) {
        return array($k => addPrice($name, $price, $v));  
      }
      else {
        return array($k => $v);
      }
    },
    $data
  ));
}

Another formulation for arrayMapWithKey is to instead copy the keys with the value and then using a regular array_map.

function arrayWithKeys(array $array) {
  $out = array();
  foreach ($array as $key => $value) {
    // in PHP arrays are often used as tuples,
    // and here we have a 2-tuple.
    $out[] = array($key, $value);
  }
  return $out;
}

这篇关于递归迭代多维数组,并返回相同的数组结构,并在PHP中插入新的键/值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆