递归迭代多维数组,返回相同的数组结构,并在PHP中插入新的键/值

递归迭代多维数组,返回相同的数组结构,并在PHP中插入新的键/值,php,arrays,recursion,multidimensional-array,spl,Php,Arrays,Recursion,Multidimensional Array,Spl,我正在尝试编写一个代码段,该代码段采用多维数组,并在找到命名搜索键的同一级别插入一些键。 我不必依赖阵列的结构(但最多为5级) 我不能使用引用传递,所以传统的循环函数对这种方法没有帮助 我有两个选择:SPL或递归,它可以重新构造数组并在过程中对其进行修改 使用SPL,我似乎无法插入新值 $a= new \ArrayObject($priceConfig); $array = new \RecursiveArrayIterator($a);

我正在尝试编写一个代码段,该代码段采用多维数组,并在找到命名搜索键的同一级别插入一些键。 我不必依赖阵列的结构(但最多为5级) 我不能使用引用传递,所以传统的循环函数对这种方法没有帮助

我有两个选择:SPL或递归,它可以重新构造数组并在过程中对其进行修改

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

            $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());
它不会在所需级别插入新密钥,但会在数组中循环。。我错过了什么

递归函数可以重建数组并在嵌套数组中的键搜索中插入新值,但我想使用迭代器来实现这一点

             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;
            }
输入(总是有一些“X级关键价格和结构”)

输出

[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
            )
    )

)

您可以通过使用自定义迭代器逻辑扩展
递归ArrayIterator
来使用迭代器:

class Foo extends RecursiveArrayIterator
{
    public function getChildren()
    {
        if ($this->key() == 'prices') {
            return new self(array_merge($this->current(), ['foo' => 'bar']));
        } else {
            return parent::getChildren();
        }
    }
}

通过使用自定义迭代器逻辑扩展
RecursiveArrayIterator
,可以使用迭代器实现这一点:

class Foo extends RecursiveArrayIterator
{
    public function getChildren()
    {
        if ($this->key() == 'prices') {
            return new self(array_merge($this->current(), ['foo' => 'bar']));
        } else {
            return parent::getChildren();
        }
    }
}

您可以使用基本工具(如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); 
    }
  }
  return $array;
}

// Example
$output = mergeWithKey('prices', array('INSERTEDPrice' => 'value'), $input);
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
  ));
}
简单地说,当我们在数组中迭代时,如果我们找到了要查找的键,那么我们将合并到新的价格中。如果我们找到一个子数组,那么我们将新的价格合并到该子数组中

我将关键的“价格”作为一个参数,努力推广该函数。这可能仍然是一个不可靠的函数,不太可能看到重用

有了两种常见的算法,您就可以很好地实现这个功能,而且好处是您可以重用这些算法。一种是用键和值映射数组,另一种是将二维数组展平为一维数组

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);
  }
}
这些定义使您能够编写替代解决方案

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);
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
  ));
}
arrayMapWithKey
的另一个公式是用值复制键,然后使用常规的
array\u映射

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

您可以使用基本工具(如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); 
    }
  }
  return $array;
}

// Example
$output = mergeWithKey('prices', array('INSERTEDPrice' => 'value'), $input);
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
  ));
}
简单地说,当我们在数组中迭代时,如果我们找到了要查找的键,那么我们将合并到新的价格中。如果我们找到一个子数组,那么我们将新的价格合并到该子数组中

我将关键的“价格”作为一个参数,努力推广该函数。这可能仍然是一个不可靠的函数,不太可能看到重用

有了两种常见的算法,您就可以很好地实现这个功能,而且好处是您可以重用这些算法。一种是用键和值映射数组,另一种是将二维数组展平为一维数组

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);
  }
}
这些定义使您能够编写替代解决方案

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);
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
  ));
}
arrayMapWithKey
的另一个公式是用值复制键,然后使用常规的
array\u映射

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

请包括示例输入和输出,以便我们更好地理解问题。添加所需输出和提供输入请包括示例输入和输出,以便我们更好地理解问题。添加所需输出和提供输入我将选择您的答案,因为它更完整,我也很喜欢SPL的答案,OOP比Alghoritms更多我会选择你的答案,因为它更完整,我也很喜欢SPL的答案,OOP比Alghoritms更多