doubu1970 2019-05-21 20:08
浏览 75
已采纳

PHP数组按类别分组

I have a list of stores and they can have multiple categories.

Today i display each store multiple times, one line with only one category.

How can i group the stores, creating an array of their categories, so the store is displayed only one time and have their multiple categories ?

This is my attempt:

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {

    array_push(
        $stores,
        [
            "id"=> $row["id"],
            "name"=> $row["nome"],
            "categories"=> array([
                "name"=> $row["categories"]
                //how can i have an array of categories
            ])
        ]
    );
}

This is how i display the json result:

{
    id: 74,
    name: "First Store",
    categories: [
        {
            name: "Clothes"
        }
    ]
},
{
    id: 1,
    name: "Second Store",
    categories: [
        {
            name: "Food"
        }
    ]
},
{
    id: 1,
    name: "Second Store",
    categories: [
        {
            name: "Toys"
        }
    ]
},

This is how i need to show the Json:

{
    id: 74,
    name: "First Store",
    categories: [
        {
            name: "Clothes"
        }
    ]
},
{
    id: 1,
    name: "Second Store",
    categories: [
        {
            name: "Food"
        },
        {
            name: "Toys"
        }
    ]
},

In my attempt i try inside the while to create the categories but have a php warning: end() expects parameter 1 to be array, null given

if( isset($stores) ) {
    if(  end($stores['id']) != $row["id"] )  {
            array_push($category_array, $row["categories"]);
    }
} 
  • 写回答

1条回答 默认 最新

  • douyingtai6662 2019-05-21 20:40
    关注

    I believe you are looking for something like this when processing your returned MySQL rows to json_encode: https://3v4l.org/d4Wf2

    This will place the stores in 1 temp $storeTracker array with the store id as the array key (this assumes store id is a constant in each record you're getting back and is always the same). From here you can then check if the array key (store id) already exists, and if so, continue to add categories to the store if the category doesn't already exist. After doing this, you can then parse to json_encode to create a valid JSON object to return. Granted there may be a more eloquent way to achieve this, but this showcases the array manipulation and whatnot to try and group data for your case.

    <?php
    
    // Data coming from MySQL Database
    $rowData = [];
    $rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'Food'];
    $rowData[] = ['id' => 74, 'name' => 'First Store', 'categories' => 'DVDs'];
    
    $rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Food'];
    $rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
    $rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Toys'];
    $rowData[] = ['id' => 1, 'name' => 'Second Store', 'categories' => 'Clothing'];
    
    $rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Toys'];
    $rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
    $rowData[] = ['id' => 3, 'name' => 'Third Store', 'categories' => 'Clothing'];
    
    /**
     * Check if store category name already added to store record
     */
    function categoryExistsAlready($categories, $category) {
        foreach($categories as $key => $catArr) {
            if(strtolower($catArr['name']) === strtolower($category)) {
                return true;
            }
        }
        return false;
    }
    
    $storeTracker = [];
    foreach($rowData as $key => $storeData) {
    
        $storeCategory = $storeData['categories'];
        $storeId = $storeData['id'];
    
        // If store exists, add category to categories array
        if (array_key_exists($storeId, $storeTracker)) {
            if (!categoryExistsAlready($storeTracker[$storeId]['categories'], $storeCategory)) {
                $storeTracker[$storeId]['categories'][] = ['name' => $storeCategory];
            }
            continue;
        }
    
        // Update store categories to be array with category
        $storeData['categories'] = [];
        $storeData['categories'][] = ['name' => $storeCategory];
    
        // Add store data to overall tracking array
        $storeTracker[$storeId] = $storeData;
    }
    
    // Format JSON response
    $jsonReturn = '[';
    $i = count($storeTracker);
    foreach($storeTracker as $storeId => $storeData) {
        $i--;
        $jsonReturn .= json_encode($storeData);
        // Determine last comma separating objects
        if ($i > 0) {
            $jsonReturn .= ',';
        }
    }
    $jsonReturn .= ']';
    
    echo $jsonReturn;
    

    Will give you this valid JSON https://jsonlint.com/:

    [{
        "id": 74,
        "name": "First Store",
        "categories": [{
            "name": "Food"
        }, {
            "name": "DVDs"
        }]
    }, {
        "id": 1,
        "name": "Second Store",
        "categories": [{
            "name": "Food"
        }, {
            "name": "Toys"
        }, {
            "name": "Clothing"
        }]
    }, {
        "id": 3,
        "name": "Third Store",
        "categories": [{
            "name": "Toys"
        }, {
            "name": "Clothing"
        }]
    }]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路