I have the following performance problem in PHP code. An external API that I cannot edit, returns a JSON array like this one:
[{"name": "Name 1", "code": "Code 1", "attribute1": "Black", "attribute2": "32", "price": "10"},
{"name": "Name 2", "code": "Code 2", "attribute1": "Yellow", "attribute2": "", "price": "15"},
{"name": "Name 1", "code": "Code 3", "attribute1": "Yellow", "attribute2": "32", "price": "20"},....
]
I want to group this by name
and reformat it to a JSON array like this:
[{
"name": "Name 1",
"available_attributes": [ "size", "color" ],
"variations": [
{ "attributes": { "size": "32", "color": "Black" }, "price": "10", "code": "Code 1"},
{ "attributes": { "size": "32", "color": "Yellow" }, "price": "20", "code": "Code 3"}
]
}, {
"name": "Name 2",
"available_attributes": [ "color" ],
"variations": [ { "attributes": { "color": "Yellow" }, "price": "15", "code": "Code 2"}]
}]
My solution is ugly and time-consuming since I used a simple brute force to iterate on the response and then again every time on the array to update the one I have already there.
So, I am looking for a solution focused on performance and speed.
Edit. This is my code. The only difference is that in case of both attributes being empty, instead of the variations and available_attributes arrays, it has the price and the sku only.
function cmp( $a, $b ) {
if ( $a['name'] == $b['name'] ) {
return 0;
}
return ( $a['name'] < $b['name'] ) ? - 1 : 1;
}
function format_products_array($products) {
usort( $products, "cmp" );
$formatted_products = array();
$new = true;
$obj = array();
for ( $i = 0; $i < count( $products ); $i++ ) {
if ( $new ) {
$obj = array();
$attr = array();
$obj['available_attributes'] = array();
$obj['variations'] = array();
$obj['name'] = $products[$i]['name'];
if ( $products[$i]['attribute1'] != '' ) {
array_push( $obj['available_attributes'], 'color' );
$attr['color'] = $products[$i]['attribute1'];
}
if ( $products[$i]['attribute2'] != '' ) {
array_push( $obj['available_attributes'], 'size' );
$attr['size'] = $products[$i]['attribute2'];
}
}
if ( $products[ $i ]['name'] == $products[ $i + 1 ]['name']) {
$new = false;
$attr['size'] = $products[$i]['attribute2'];
$attr['color'] = $products[$i]['attribute1'];
if ( empty($obj['available_attributes']) ) {
$obj['price'] = $products[$i]['price'];
} else {
$var = array();
$var['price'] = $products[$i]['price'];
$var['code'] = $products[$i]['code'];
$var['attributes'] = $attr;
array_push($obj['variations'], $var);
}
} else {
$new = true;
if ( empty($obj['available_attributes']) ) {
$obj['price'] = $products[$i]['price'];
}
$attr['size'] = $products[$i]['attribute2'];
$attr['color'] = $products[$i]['attribute1'];
$var['attributes'] = $attr;
array_push($obj['variations'], $var);
array_push($formatted_products, $obj);
}
}
return $formatted_products;
}