我正在构建一个[post,comments]项目,其中帖子详细信息存储在posts表中,注释详细信息存储在comments表中。该项目由Laravel(Php)生成。这是一段代码。
//get data from Post table
$posts = $this->postsRepo->getAllPosts();
//get data from comments table
$comments = $this->commentRepo->getAllComments();
print_r($posts);
print_r($comments);
发布表的结果
Array
(
[0] => stdClass Object
(
[id] => 1
[post_text] => This is a test post
)
)
[1] => stdClass Object
(
[id] => 2
[post_text] => This is another test
)
)
评论表的结果
Array
(
[0] => stdClass Object
(
[id] => 1
[post_id] => 1
[comments_text] => This is a test comment 1
)
[1] => stdClass Object
(
[id] => 2
[post_id] => 1
[comments_text] => This is a test comment 2
)
)
现在我想要像
这样的结果Array
(
[0] => stdClass Object
(
[id] => 1
[post_title] => This is a test post
[comments] => Array
(
[0] => stdClass Object
(
[id] => 1
[post_id] => 1
[comment_text] => This is a test comment 1
)
[1] => stdClass Object
(
[id] => 2
[post_id] => 1
[comment_text] => This is a test comment 2
)
)
)
)
[1] => stdClass Object
(
[id] => 2
[post_title] => This is another test
[comments] => Array()
)
)
我使用了以下技术,它正在运作
foreach ($posts as $postIndex => $post) {
foreach ($comments as $commentIndex => $comment) {
if($post->id == $comment->post_id) {
$posts[$postIndex]->comments[] = $comment;
}
}
}
还有其他方法可以在发布 for循环中运行评论。我将post_id发送到评论表。但随着数据的增加,这项技术将变得缓慢
有人可以建议更好的技术来解决这个问题吗? 另外,我使用Repository设计模式获取帖子和&评论
答案 0 :(得分:1)
有几种方法可以执行此操作,具体取决于您使用的PHP版本(尽管1将始终有效)。主要原则是通过ID索引其中一个数组,这样您就可以使用索引来设置值,而不是循环遍历两个数组。由于每个帖子都可以有多个评论,因此通过ID索引帖子并在评论中循环,将它们添加到正确的帖子中似乎更容易......
$posts = [
(object)[
"id" => 1,
"post_text" => "This is a test post"
],
(object)[
"id" => 2,
"post_text" => "This is another test"
]
];
$comments = [(object)
[
"id" => 1,
"post_id" => 1,
"comments_text" => "This is a test comment 1"
],
(object)
[
"id" => 2,
"post_id" => 1,
"comments_text" => "This is a test comment 2"
]
];
$postIndex = array_column($posts, null, "id");
//$postIndex = array_reduce($posts, function ($result, $post) { // PHP pre 7
// $result[$post->id] = $post;
// return $result;
//}, array());
foreach ( $comments as $comment ) {
$postIndex[ $comment->post_id ]->comments[] = $comment;
}
echo "<pre>";
print_r($postIndex);
...输出
Array
(
[1] => stdClass Object
(
[id] => 1
[post_text] => This is a test post
[comments] => Array
(
[0] => stdClass Object
(
[id] => 1
[post_id] => 1
[comments_text] => This is a test comment 1
)
[1] => stdClass Object
(
[id] => 2
[post_id] => 1
[comments_text] => This is a test comment 2
)
)
)
[2] => stdClass Object
(
[id] => 2
[post_text] => This is another test
)
)
唯一的区别是,从PHP 7.0开始,您可以将array_column()
与对象数组一起使用。在此之前,您必须手动进行转换。
答案 1 :(得分:0)
你最好使用雄辩的关系...... 但要回答你当前案件的问题,如果你需要用php方式完成这个。
// for all the post of the posts array
foreach ($posts as $key => $value) {
// get comments which only belongs to the post
$post_comments = [];
foreach ($comments as $comment) {
if ($comment['post_id'] == $value['id']) {
array_push($post_comments, $comment);
}
}
// add a new attribute (comments) to each post
// set created comments array of the post
$post[$key]['comments'] = $post_comments;
}
答案 2 :(得分:0)
如果您循环发布,则可以使用array_intersect和array_intersect_key 这意味着您只需循环一个数组,但使用数组函数来获取正确的注释 这意味着数组必须是数组而不是对象。
Foreach($posts as $key => $post){
$matches = array_intersect(array_column($comments, "post_id"), [$post["id"]]);
$new[$key][] = $post;
$new[$key]["comments"][] = array_intersect_key($comments, $matches);
}
Var_dump($new);