递归如果标量,数组

我有一些默认配置,以及一些可配置的特定配置。 我需要将特定配置合并到默认配置中。

  • 在特定配置选项不存在的情况下,将使用默认选项。
  • value标量的情况下,应该应用特定的配置
  • value标量数组的情况下,应该合并数组并应用array_unique。
  • value关联数组的情况下,我们需要应用上面的scalarscalar_array规则。
  • 例:

    $defaultConfigs = [
       'scalar1' => 1,
       'scalar2' => "Apple",
       'array_scalar' => [3,4,5],
       'array_associative' => [
          'scalar' => 1,
          'array_scalar' => [1,2,3],
          'array_associative' => [
              ...
          ]
       ],
    ];
    
    $specificConfigs = [
       'scalar1' => "A",                          
       'array_scalar' => [3,4,5],   
       'array_associative' => [
          'scalar' => 1,
          'array_scalar' => [1,2,3],
          'array_associative' => [
              ...
          ]
       ],
    ];
    

    预期产出:

    $expectedConfigs = [
       'scalar1' => "A",                  // Overridden
       'scalar2' => "Apple",              // Default used
       'array_scalar' => [1,2,3,4,5],     // Scalar merged and array_unique
       'array_associative' => [
          'scalar' => "B",                // Overridden
          'array_scalar' => [1,2,3,4,5],  // Scalar merged and array_unique
          'array_associative' => [
              ...
          ]
       ],
    ];
    

    有没有一个很好的干净方式来实现这一目标?


    该功能可以获得您想要的结果。 它假定特定类型是默认类型的一致性,所以不执行一致性检查。 该函数迭代特定的配置数组并检查相应的默认值1:如果它是标量,则替换默认值; 如果它是一个枚举数组2,它将合并唯一值; 否则函数以当前值作为参数调用自身。

    function fillConfig( $default, $specific )
    {
        foreach( $specific as $key=> $val )
        {
            if( isset( $default[$key] ) )
            {
                if( ! is_array( $default[$key] ) )
                {
                    $default[$key] = $val;
                }
                elseif( array_keys($default[$key]) === range(0, count($default[$key]) - 1) )
                {
                    $default[$key] = array_unique( array_merge( $default[$key], $val ) );
                }
                else
                {
                    $default[$key] = fillConfig( $default[$key], $val );
                }
            }
            else
            {
                // This happens when a specific key doesn't exists in default configuration.
                // I think that in this case the value must be omitted,
                // otherwise you can un-comment following line:
                // $default[$key] = $val;
            }
        }
        return $default;
    }
    

    以这种方式调用函数:

    $result = fillConfig( $defaultConfigs, $specificConfigs );
    

    $result ,应用于你的数组示例,是这样的:

    Array
    (
        [scalar1] => A
        [scalar2] => Apple
        [array_scalar] => Array
            (
                [0] => 3
                [1] => 4
                [2] => 5
            )
        [array_associative] => Array
            (
                [scalar] => 1
                [array_scalar] => Array
                    (
                        [0] => 1
                        [1] => 2
                        [2] => 3
                    )
                [array_associative] => Array
                    (
                    )
            )
    )
    

    有了这个阵列夫妇:

    $defaultConfigs = [
       'scalar1' => 1,
       'scalar2' => "Apple",
       'array_scalar' => [3,4,5],
       'array_associative' => [
          'scalar' => 1,
          'array_scalar' => [1,2,3],
          'array_associative' => [
    
          ]
       ],
    ];
    
    $specificConfigs = [
       'scalar1' => "A",                          
       'array_scalar' => [3,4,5],   
       'array_associative' => [
          'scalar' => B,
          'array_scalar' => [3,4,5],
          'array_associative' => [
    
          ]
       ],
    ];
    

    $result是:

    Array
    (
        [scalar1] => A
        [scalar2] => Apple
        [array_scalar] => Array
            (
                [0] => 3
                [1] => 4
                [2] => 5
            )
    
        [array_associative] => Array
            (
                [scalar] => B
                [array_scalar] => Array
                    (
                        [0] => 1
                        [1] => 2
                        [2] => 3
                        [4] => 4
                        [5] => 5
                    )
    
                [array_associative] => Array
                    (
                    )
    
            )
    
    )
    

    笔记:

    1是的,这有点不一致:我觉得更好地遍历特定的数组(不存在的项目保持不变),但在默认数组上执行值检查,即参考点。

    2枚举/关联数组检查基于这个答案。


    我的情况稍有不同,但可能有所帮助。 我需要替换数组上的标量和array_merge_recursive。

    class ArrayUtil {
    
        public static function mergeRecursive(array $array1, $array2) {
            if($array2 && is_array($array2)) {
                foreach($array2 as $key => $val2) {
                    if (is_array($val2) && (null!==($val1 = isset($array1[$key]) ? $array1[$key] : null)) && is_array($val1)) {
                        $array1[$key] = self::mergeRecursive($val1,$val2);
                    } else {
                        $array1[$key] = $val2;
                    }
                }
            }
            return $array1;
        }
    }
    

    我使用config数组重新编写了第一个答案中的函数:

    private function mergeConfigs(array $configs): array
    {
        $default = array_shift($configs);
        return array_reduce($configs, function (array $result, array $config) {
            foreach ($config as $key => $val) {
                if (!isset($result[$key]) || !is_array($result[$key])) {
                    $result[$key] = $val;
                    continue;
                }
                $result[$key] = array_keys($result[$key]) === range(0, count($result[$key]) - 1)
                    ? array_unique(array_merge($result[$key], $val))
                    : $this->mergeConfigs([$result[$key], $val]);
            }
            return $result;
        }, $default);
    }
    
    链接地址: http://www.djcxy.com/p/32163.html

    上一篇: recursive if scalar, array

    下一篇: Publish a single iOS message to multiple AWS SNS Topics