在PHP中对一组对象进行分组和重新格式化

时间:2017-10-10 12:04:47

标签: php arrays

我在PHP代码中遇到以下性能问题。我无法编辑的外部API,返回一个像这样的JSON数组:

[{"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"},....
]

我希望按name对此进行分组,并将其重新格式化为这样的JSON数组:

[{
   "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"}]
}]

我的解决方案是丑陋而耗时的,因为我使用简单的蛮力来迭代响应,然后每次在阵列上再次更新我已经存在的那个。

所以,我正在寻找一个专注于性能和速度的解决方案。

修改。这是我的代码。唯一的区别是,如果两个属性都是空的,而不是变体和available_attributes数组,它只有价格和sku。

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;
}

1 个答案:

答案 0 :(得分:0)

更快的解决方案是生成数组以存储唯一标识或每个对象,例如生成:

[
  "Name1":{
   "name": "Name 1",
   "code": "Code 1",
   "available_attributes": [ "size", "color" ],
   "variations": [ 
       { "attributes": { "size": "32", "color": "Black" }, "price": "10"},
       { "attributes": { "size": "32", "color": "Yellow" }, "price": "20"}
   ]
  },
  "Name2": {
   "name": "Name 2",
   "code": "Code 2",
   "available_attributes": [  "color" ],
   "variations": [ { "attributes": { "color": "Yellow" }, "price": "15"}]
}]

OR

[
  "Code 1":{
   "name": "Name 1",
   "code": "Code 1",
   "available_attributes": [ "size", "color" ],
   "variations": [ 
       { "attributes": { "size": "32", "color": "Black" }, "price": "10"},
       { "attributes": { "size": "32", "color": "Yellow" }, "price": "20"}
   ]
  },
  "Code 2": {
   "name": "Name 2",
   "code": "Code 2",
   "available_attributes": [  "color" ],
   "variations": [ { "attributes": { "color": "Yellow" }, "price": "15"}]
}]

之后(可选)删除任何关联。

之后您可以将它们存储在memcached / redis中,然后当您需要重新检索相同的数据时,再先查看redis / memcached。

所以一开始可能会耗费时间,但之后它会做好准备,所以他们只会选择“不幸”的家伙/女孩做同样的事情。

如果它是极其耗时的循环,那么使用工作人员生成数据并将它们存储在基于文档的存储中,例如mongodb / couchdb,之后该站点将查看现成的文档。