[英]Dynamically convert array to key-value pair array
This is an example of array I have:这是我拥有的数组示例:
$data = [
'total_amount' => 200,
'purchase_date' => '01.01.2020',
'items' => [
[
'name' => 'T-shirt',
'price' => 50
],
[
'name' => 'Jacket',
'price' => 150
],
]
];
and I would like to get something like this:我想得到这样的东西:
$data = [
[
'k' => 'total_amount',
'v' => 200
],
[
'k' => 'purchase_date',
'v' => '01.01.2020'
]
[
'k' => 'items',
'v' => [
[
[
'k' => 'name',
'v' => 'T-Shirt'
],
[
'k' => 'price',
'v' => 50
]
],
[
[
'k' => 'name',
'v' => 'Jacket'
],
[
'k' => 'price',
'v' => 150
]
]
]
]
]
It's not a big problem to parse the first array and then create desired output.解析第一个数组,然后创建所需的 output 问题不大。 Also, if we have nested and nasted and nested array, then I just use a recursion and it seems to work pretty good.
此外,如果我们有嵌套和嵌套数组,那么我只使用递归,它似乎工作得很好。 Here is the code I have:
这是我的代码:
public function convert(array $data) : array
{
$output = [];
foreach ($data as $k => $v) {
if (is_array($v)) {
$output[] = ['k' => $k, 'v' => $this->value($v)];
} else {
$output[] = ['k' => $k, 'v' => $v];
}
}
return $output;
}
and the following:以及以下内容:
protected function value($items)
{
$output = [];
$i = 0;
foreach ($items as $itemK => $itemV) {
if (!is_array($itemV)) {
$output[$i] = ['k' => $itemK, 'v' => $itemV];
continue;
}
foreach ($itemV as $k => $v) {
if (is_array($v)) {
$output[$i][] = ['k' => $k, 'v' => $this->value($v)];
continue;
}
$output[$i][] = ['k' => $k, 'v' => $v];
}
$i++;
}
return $output;
}
The question is if there is a way to optimize this code without using too many foreach functions (maybe there is built-in PHP function that I can leverage) and maybe avoid recursion?问题是是否有一种方法可以在不使用太多 foreach 函数的情况下优化此代码(也许有内置的 PHP function 我可以利用)并且可能避免递归?
Here's a slightly simplified version of your code.这是您的代码的稍微简化的版本。 Note that if you want to allow arbitrarily nested key/value pairs, recursion is the only effective method to do that:
请注意,如果您想允许任意嵌套的键/值对,递归是唯一有效的方法:
function convert($array) {
$output = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
// nested array with numeric keys? if so don't create a k,v pair
if (is_numeric($key)) {
$output[] = convert($value);
}
else {
$output[] = array('k' => $key, 'v' => convert($value));
}
}
else {
$output[] = array('k' => $key, 'v' => $value);
}
}
return $output;
}
Output: Output:
Array
(
[0] => Array
(
[k] => total_amount
[v] => 200
)
[1] => Array
(
[k] => purchase_date
[v] => 01.01.2020
)
[2] => Array
(
[k] => items
[v] => Array
(
[0] => Array
(
[0] => Array
(
[k] => name
[v] => T-shirt
)
[1] => Array
(
[k] => price
[v] => 50
)
)
[1] => Array
(
[0] => Array
(
[k] => name
[v] => Jacket
)
[1] => Array
(
[k] => price
[v] => 150
)
)
)
)
)
To tighten-up / D.R.Y.-out your code, identify the processes that are written more than once and try to refactor the script in a way that will permit the single declaration of a function call or process.为了收紧/D.R.Y.-out 您的代码,识别多次编写的进程并尝试以允许 function 调用或进程的单一声明的方式重构脚本。
$value
is an array, so conditionally call&cache the recursion's return value to a variable.$value
是一个数组时你需要使用递归,所以有条件地调用&缓存递归的返回值到一个变量。 Using the following, you get your desired output without redundant scripting.使用以下内容,您将获得所需的 output 而无需冗余脚本。
function restructure($array) {
$output = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$value = restructure($value);
}
$output[] = is_int($key) ? $value : ['k' => $key, 'v' => $value];
}
return $output;
}
var_export(restructure($data));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.