将点注字符串列表转换为关联数组(PHP)

时间:2016-08-08 06:00:22

标签: php arrays multidimensional-array associative-array

我有一个字符串列表,每个字符串都包含点标记值。我想将此列表转换为关联数组,其中每个点符号段都作为相应嵌套级别中的键。最深层次的嵌套应该具有布尔值true。字符串可以包含的数字或点段没有限制,因此代码需要进行某种递归才能实现目标。

输入示例:

[
    'foo.bar',
    'foo.bar.baz',
    'foo.bar.qux',
    'foo.qux',
    'foo.quux',
    'bar.baz',
    'bar.qux',
    'qux.quux',
]

必需的输出:

[
    'foo' => [
        'bar' => [
            'baz' => true,
            'qux' => true,
        ],
        'qux' => true,
        'quux' => true,
    ],
    'bar' => [
        'baz' => true,
        'qux' => true,
    ],
    'qux' => [
        'quux' => true
    ]
]

4 个答案:

答案 0 :(得分:1)

foreach只有解决方案。

function convert(array $input)
{
    $r = [];
    foreach ($input as $dotted) {
        $keys = explode('.', $dotted);
        $c = &$r[array_shift($keys)]; 
        foreach ($keys as $key) {
            if (isset($c[$key]) && $c[$key] === true) {
                $c[$key] = [];
            }
            $c = &$c[$key];
        }
        if ($c === null) {
            $c = true;
        }
    }
    return $r;
}

答案 1 :(得分:0)

如果您调用字符串$input的起始数组,则下面代码中的$output数组就是您想要的

$input=[...]; //original array
$output=[];   //holds the results;
foreach ($input as $line){
    $keys = explode('.',$line);//break each section into a key
    $val = true;               //holds next value to add to array
    $localArray = [];          //holds the array for this input line
    for($i=count($keys)-1; $i>=0; $i--){ //go through input line in reverse order
        $localArray = [$keys[$i]=>$val]; //store previous value in array
        $val = $localArray;           //store the array we just built. it will be
                                      //the value in the next loop
    }
    $output = array_merge_recursive($output,$localArray);
}

Live demo

答案 2 :(得分:0)

function convert($aa) {
  $zz = [];
  foreach( $aa as $value ) {
    $bb = explode('.',$value);
    $cc = count($bb);
    for( $ii = 0, $yy = &$zz; $ii < $cc ; $ii++ ) {
      $key = $bb[$ii];
      if ( array_key_exists($key,$yy) === false || is_array($yy[$key]) === false ) {
        $yy[$key] = [];
      }
      $yy = &$yy[$key];
    }
    $key = $bb[$cc-1];
    if ( array_key_exists($key,$yy) === false ) {
        $yy[$key] = true;
    }
  }
  return $zz;
}

答案 3 :(得分:0)

你可以使用指针和一些逻辑来做到这一点。

<?php
$test = [
    'foo.bar',
    'foo.bar.baz',
    'foo.bar.qux',
    'foo.qux',
    'foo.quux',
    'bar.baz',
    'bar.qux',
    'qux.quux',
];

class Test
{
    public $result = [];

    public function check($array){
        foreach ($array as $value) {
            $this->change($value);
        }
    }

    public function change($string)
    {
        $explodedValues = explode('.',$string);

        $pointerVariable = &$this->result;

        foreach ($explodedValues as $explodedValue) {

            if(!is_array($pointerVariable)){
                $pointerVariable = [];
                $pointerVariable[$explodedValue] = true;
                $pointerVariable = &$pointerVariable[$explodedValue];
            } else if(isset($pointerVariable[$explodedValue])){
                $pointerVariable = &$pointerVariable[$explodedValue];
            } else {
                $pointerVariable[$explodedValue] = true;
                $pointerVariable = &$pointerVariable[$explodedValue];
            }

        }
    }
}

$obj = new Test();
$obj->check($test);

print_r($obj->result);

希望这会有所帮助