Преобразуйте структуру массива в php - PullRequest
0 голосов
/ 24 сентября 2019

Если у меня есть массив из базы данных, такой как:

$array = [  
    'dataset_1' => [
        'some' => '...',
        'array' => '...',
    ],  
    'dataset_2' => [
        'some' => '...',
        'thing' => '...',
        'else' => '...', 
    ] 
];

... как я могу преобразовать этот массив в другую структуру, такую ​​как:

$array = [ 
    'whatever' => [
        'some' =>'...',
        'array' => '...',
        'some' =>'...',
        'thing' => '...',
        'else' => '...',
    ] 
];

Я думало OptionResolver, но я понятия не имею, так что если кто-нибудь может дать мне подсказку или пример?

Ответы [ 5 ]

2 голосов
/ 24 сентября 2019

Вы можете сделать это, используя array_merge вместе с ..., если у вас есть неизвестное количество наборов данных, чтобы получить свой результат.Однако будьте осторожны, поскольку у вас есть дубликаты ключей в ваших массивах, что означает, что вы потеряете все дубликаты ключей, кроме одного.Попробуйте использовать уникальные ключи:

$input = array(  
   'dataset_1'=>[
      'some' =>'...',
      'array' => '...', ],  
   'dataset_2'=>[
      'some' =>'...',
      'thing' => '...',
      'else' => '...', 
   ] 
);


$output['whatever'] = array_merge(...array_values($input));
print_r($output);

Вывод:

Array
(
    [whatever] => Array
        (
            [some] => ...
            [array] => ...
            [thing] => ...
            [else] => ...
        )

)
0 голосов
/ 27 сентября 2019

На самом деле, я делаю это путем построения целевого массива в виде шаблона, например:

Source array:
$array = [  
        'dataset_1' => [
            'keyFromSourceArray' => 'someValue',
            'array' => '...',
        ];

Массив назначения:

$array = [  
        'dataset_somename' => [
            'dataset_somename' => [
                'some' => 'keyFromSourceArray',
                'array' => '...',
        ],
];

Затем я прокручиваю исходный массив, перехватываюключи, поиск и замена его по значению в массиве назначения, например:

public function array2api($needle, $array=false, array $path = []) {
foreach ($array as $key => $value) {
  $currentPath = array_merge($path, [$key]);
  if (is_array($value) && $result = $this->array2api($needle, $value, $currentPath)) {
    return $result;
  } else if ($value === $needle) {
    return $currentPath;
  }
}
return false;
}

Это работает, но это - я думаю, немного трудоемко.Так как я не могу получить исходные данные из БД, я все равно должен их преобразовать.Но я думаю, что есть гораздо более простое решение, которое я еще не получил.

0 голосов
/ 25 сентября 2019

Один простой способ сделать это, не допуская дублирования ключей, - это объединить родительский и дочерний ключи с рекурсивным циклом:

$array = [  
    'dataset_1' => [
        'some' => '...',
        'array' => '...',
    ],  
    'dataset_2' => [
        'some' => '...',
        'thing' => '...',
        'else' => '...', 
    ] 
];
$flat_array = [];

foreach($array as $dataset => $data){
    foreach($data as $index => $value){
        $flat_array[$dataset . '_' . $index] = $value;
    }
}

var_export($flat_array);

Выходы:

array (
  'dataset_1_some' => '...',
  'dataset_1_array' => '...',
  'dataset_2_some' => '...',
  'dataset_2_thing' => '...',
  'dataset_2_else' => '...',
)

Если вашданные становятся более сложными, вы можете применить эту же логику внутри рекурсивной функции, которая может обрабатывать множество вложенных слоев:

$array = [  
    'dataset_1' => [
        'some' => '...',
        'array' => '...',
    ],  
    'dataset_2' => [
        'some' => '...',
        'thing' => '...',
        'else' => [
            'cheese' => [
                'ball'  => true,
                'wheel' => false
                ],
            ], 
    ] 
];

function array_flatten ($array)
{
    $result = [];
    foreach($array as $i => $value)
    {
        if(!is_array($value)){
            $result[$i] = $value;
        }else{
            // pass array $value back to this same function
            $sub_result = array_flatten($value);
            foreach($sub_result as $subI => $subV)
            {
                // concatenate this index with each sub-index 
                // to get result index for each sub-value
                $result[$i . '_' . $subI] = $subV;
            }                
        }
    }
    return $result;
}

var_export(array_flatten($array));

Выходы:

array (
  'dataset_1_some' => '...',
  'dataset_1_array' => '...',
  'dataset_2_some' => '...',
  'dataset_2_thing' => '...',
  'dataset_2_else_cheese_ball' => true,
  'dataset_2_else_cheese_wheel' => false,
)
0 голосов
/ 25 сентября 2019

Чтобы избежать перезаписи дубликатов ключей, используйте это.Таким образом, дубликаты ключей в массиве будут последовательно принимать целое число.

// New array
foreach ($array as $key => $sub_array):
    foreach ($sub_array as $sub_key => $value):
        if (array_key_exists($sub_key,$new_array['whatever'])) {
            $i{$sub_key} = !isset($i{$sub_key}) ? 0 : $i{$sub_key};
            $sub_key = $sub_key . ++$i{$sub_key};
        }
        $new_array['whatever'][$sub_key] = $value;
    endforeach;
endforeach;

Например:

// Array
$array = [
    'dataset_1' => [
        'some' => '...',
        'array' => '...',
    ],
    'dataset_2' => [
        'some' => '...',
        'thing' => '...',
        'else' => '...',
    ],
    'dataset_3' => [
        'some' => '...',
        'thing' => '...',
        'else' => '...',
    ]
];

// New array
// the code...

print_r($new_array);

Вывод:

Array ( 
    [whatever] => Array ( 
        [some] => ... 
        [array] => ... 
        [some1] => ... 
        [thing] => ... 
        [else] => ... 
        [some2] => ... 
        [thing1] => ... 
        [else1] => ... 
        [some3] => ... 
        [thing2] => ... 
        [else2] => ... 
    ) 
)

0 голосов
/ 24 сентября 2019

Вы потеряете дубликат ключа 'some' в обоих примерах ниже.

$a = [  
   'dataset_1'=>[
      'some' =>'...',
      'array' => '...', ],  
   'dataset_2'=>[
      'some' =>'...',
      'thing' => '...',
      'else' => '...', 
   ] 
];

// You can use array union operator
$b = $a['dataset_1'] + $a['dataset_2'];

// Or you can use array merge.
$b = array_merge($a['dataset_1'], $a['dataset_2']);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...