在Laravel 4或5中使用Eloquent时,$model->with()
方法将该方法用作关系名称。因此,如果我们向用户提供他的个人资料,那么将返回:
$user = [
'id' => 1,
'name' => 'Example',
'profile' => [
'last_login' => '10-10-1900',
'another_field' => 'with some data',
'actions' => [
0 => 'Logged in',
1 => 'Logged out',
2 => 'Signed up for news letter'
]
]
];
我想展平整个数组并使用关系的键作为前缀,即例如:
$user = [
'id' => 1,
'name' => 'Example',
'profile_last_login' => '10-10-1900',
'profile_another_field' => 'with some data',
'profile_actions' => [
0 => 'Logged in',
1 => 'Logged out',
2 => 'Signed up for news letter'
]
];
我怎样才能做到这一点?
修改
我也想要展平多维数组,如下所示:
$user = [
'id' => 1,
'name' => 'Example',
'profile' => [
'last_login' => '10-10-1900',
'another_field' => 'with some data',
'actions' => [
0 => 'Logged in',
1 => 'Logged out',
2 => 'Signed up for news letter'
],
'friends' => [
'friend_one' => [
'name' => 'Test User',
'email' => 'test@example.com'
],
'friend_two' => [
'name' => 'Test User',
'email' => 'test@example.com'
]
]
]
];
进入这个:
$out = [
'id' => 1,
'name' => 'Example',
'profile_last_login' => '10-10-1900',
'profile_another_field' => 'with some data',
'profile_actions' => [
0 => 'Logged in',
1 => 'Logged out',
2 => 'Signed up for news letter'
],
'profile_friends_friend_one_name' => 'Test User',
'profile_friends_friend_one_email' => 'test@example.com',
'profile_friends_friend_two_name' => 'Test User',
'profile_friends_friend_two_email' => 'test@example.com'
];
答案 0 :(得分:0)
function flattenParentKey($array, $parentKey)
{
foreach ($array[$parentKey] as $key => $value)
{
$array[$parentKey . '_' . $key] = $value;
}
unset($array[$parentKey]);
return $array;
}
这是PHP Shell中的一个示例(php -a
):
php > $user = [
php > 'id' => 1,
php > 'name' => 'Example',
php > 'profile' => [
php > 'last_login' => '10-10-1900',
php > 'another_field' => 'with some data',
php > 'actions' => [
php > 0 => 'Logged in',
php > 1 => 'Logged out',
php > 2 => 'Signed up for news letter'
php > ]
php > ]
php > ];
php > $user = flattenParentArray($user, 'profile');
php > var_dump($user);
array(5) {
["id"]=>
int(1)
["name"]=>
string(7) "Example"
["profile_last_login"]=>
string(10) "10-10-1900"
["profile_another_field"]=>
string(14) "with some data"
["profile_actions"]=>
array(3) {
[0]=>
string(9) "Logged in"
[1]=>
string(10) "Logged out"
[2]=>
string(25) "Signed up for news letter"
}
}
php >
正如您在评论中提到的那样,我添加到您原来的问题中,这里是我们如何使用嵌套的多维数组执行此操作:
$user = [
'id' => 1,
'name' => 'Example',
'profile' => [
'last_login' => '10-10-1900',
'another_field' => 'with some data',
'actions' => [
0 => 'Logged in',
1 => 'Logged out',
2 => 'Signed up for news letter'
],
'friends' => [
'friend_one' => [
'name' => 'Test User',
'email' => 'test@example.com'
],
'friend_two' => [
'name' => 'Test User',
'email' => 'test@example.com'
]
]
]
];
/* Returns true if the specified parameter is an array, is not empty, and is
* not a contiguous numeric array).
*/
function isAssociativeArray($array)
{
if (empty($array) || !is_array($array))
{
return false;
}
/* Returns true if arrays keys are not numeric or contiguous. */
return (bool) array_keys($array) !== range(0, count($array) - 1);
}
/* $parentKey will always be null when we first call this function. As
* it recurses through levels of depth, $parentKey will be passed and
* appended to.
*/
function flattenChildArrays($array, $parentKey = null)
{
$outputArray = [];
foreach ($array as $key => $value)
{
/* If we have a $parentKey, our new key will be "$parentKey_$key" */
$newKey = (($parentKey) ? $parentKey . '_' . $key : $key);
if (isAssociativeArray($value))
{
/* If our $value is an associative array, we'll want to recursively
* call ourselves again on $value with our new key as the $parentKey.
*/
$outputArray = array_merge($outputArray, flattenChildArrays($value, $newKey));
}
else
{
/* If $value is not an associative array (i.e. just a simple value, or a
* contiguous numeric array, just use the value as it is in our output
* array. If we have a parent key (because we're inside 1 or more levels
* of recursion), use "$parentKey_$key" (see where we define $newKey above).
*/
$outputArray[$newKey] = $value;
}
}
return $outputArray;
}
PHP shell中的一个例子:
php > $user = [
php > 'id' => 1,
php > 'name' => 'Example',
php > 'profile' => [
php > 'last_login' => '10-10-1900',
php > 'another_field' => 'with some data',
php > 'actions' => [
php > 0 => 'Logged in',
php > 1 => 'Logged out',
php > 2 => 'Signed up for news letter'
php > ],
php > 'friends' => [
php > 'friend_one' => [
php > 'name' => 'Test User',
php > 'email' => 'test@example.com'
php > ],
php > 'friend_two' => [
php > 'name' => 'Test User',
php > 'email' => 'test@example.com'
php > ]
php > ]
php > ]
php > ];
php > var_dump(flattenChildArrays($user));
array(11) {
["id"]=>
int(1)
["name"]=>
string(7) "Example"
["profile_last_login"]=>
string(10) "10-10-1900"
["profile_another_field"]=>
string(14) "with some data"
["profile_actions_0"]=>
string(9) "Logged in"
["profile_actions_1"]=>
string(10) "Logged out"
["profile_actions_2"]=>
string(25) "Signed up for news letter"
["profile_friends_friend_one_name"]=>
string(9) "Test User"
["profile_friends_friend_one_email"]=>
string(16) "test@example.com"
["profile_friends_friend_two_name"]=>
string(9) "Test User"
["profile_friends_friend_two_email"]=>
string(16) "test@example.com"
}
php >
递归可能是一个难以理解的主题,因为它需要您通过头脑中的多个级别来跟踪程序,并且很容易忘记您的位置。我建议采用一个简单的例子,并且"单步执行"你的递归函数,逐行,评论每个深度的每个值。
this question的答案提供了有关理解递归的更多信息。