基于单个数组项合并数组


Merging array based on a single array item

我创建了一个默认数组,我正在尝试根据默认数组中的rating和返回的数据库项替换数组中的值。我这样做是为了如果不是返回数据库中的所有ratings,我有一个默认值。

因此,当它运行时,我会得到9项目的最终列表,因为数据库中的值只是附加到列表中,但永远不会被替换。

$ratings['results'] = array_merge([
    ['rating'=>5, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>4, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>3, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>2, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>1, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
], $ratings['results']);

以下是数据库项:

array(1) {
    ["results"]=>
    array(4) {
        [0]=>
        object(stdClass)#260 (4) {
        ["rating"]=>
        int(3)
        ["rating_count"]=>
        int(2)
        ["percent"]=>
        string(7) "50.0000"
        ["average"]=>
        string(6) "3.0000"
        }
        [1]=>
        object(stdClass)#261 (4) {
        ["rating"]=>
        int(4)
        ["rating_count"]=>
        int(1)
        ["percent"]=>
        string(7) "25.0000"
        ["average"]=>
        string(6) "4.0000"
        }
        [2]=>
        object(stdClass)#262 (4) {
        ["rating"]=>
        int(5)
        ["rating_count"]=>
        int(1)
        ["percent"]=>
        string(7) "25.0000"
        ["average"]=>
        string(6) "5.0000"
        }
        [3]=>
        object(stdClass)#263 (4) {
        ["rating"]=>
        NULL
        ["rating_count"]=>
        int(4)
        ["percent"]=>
        string(8) "100.0000"
        ["average"]=>
        string(6) "3.7500"
        }
    }
}

以下是最终的 json 响应(注意:评级 = null 的项目是摘要列):

{
    "results": [
        {
            "rating": 5,
            "rating_count": 0,
            "percent": 0,
            "average": 0
        },
        {
            "rating": 4,
            "rating_count": 0,
            "percent": 0,
            "average": 0
        },
        {
            "rating": 3,
            "rating_count": 0,
            "percent": 0,
            "average": 0
        },
        {
            "rating": 2,
            "rating_count": 0,
            "percent": 0,
            "average": 0
        },
        {
            "rating": 1,
            "rating_count": 0,
            "percent": 0,
            "average": 0
        },
        {
            "rating": 3,
            "rating_count": 2,
            "percent": "50.0000",
            "average": "3.0000"
        },
        {
            "rating": 4,
            "rating_count": 1,
            "percent": "25.0000",
            "average": "4.0000"
        },
        {
            "rating": 5,
            "rating_count": 1,
            "percent": "25.0000",
            "average": "5.0000"
        },
        {
            "rating": null,
            "rating_count": 4,
            "percent": "100.0000",
            "average": "3.7500"
        }
    ]
}

它不是这样工作的。您有数字数组,array_merge

将一个或多个数组的

元素合并在一起,以便将一个数组的值追加到前一个数组的末尾。它返回结果数组。 源

除此之外,您的defaults是一个多维数组,而results是一个对象数组,因此需要进行一些转换。

你可以做这样的事情:

// fill resulting array with default values
$result = [
    ['rating'=>5, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>4, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>3, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>2, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
    ['rating'=>1, 'rating_count'=>0, 'percent'=>0, 'average'=>0],
];
// index results from the database to speed it up a bit
$indexed = [];
foreach($ratings['results'] as $rating) { 
    // be careful, if you have same rating from the db, only the last one counts
    $indexed[$rating->rating] = (array)$rating;
};
//merge line by line
array_walk(
    $result, 
    function(&$row, $key, $data) {
        if(isset($data[$row['rating']])) {
            $row = array_merge($row, $data[$row['rating']]);
        };
    },
    $indexed
);