Grouping an array’s value in PHP

Asked

Viewed 559 times

0

I have the following array:

Array
(
[0] => stdClass Object
    (
        [anomes] => 201601
        [codreg] => 41
        [nomreg] => PR
        [codcin] => 1
        [nomcin] => OUTROS
        [valven] => 6835.7000
        [qtdven] => 1078.8000
    )

[1] => stdClass Object
    (
        [anomes] => 201601
        [codreg] => 42
        [nomreg] => SC
        [codcin] => 1
        [nomcin] => OUTROS
        [valven] => 3129.0000
        [qtdven] => 366.6200
    )

[2] => stdClass Object
    (
        [anomes] => 201601
        [codreg] => 42
        [nomreg] => SC
        [codcin] => 2
        [nomcin] => PECAS
        [valven] => 346.9100
        [qtdven] => 73.6600
    )

)

and would like to group it by codreg, implemented the following:

$saida    = array();

foreach ($dadf513 as $row) {

    if(!isset($saida[$row->nomreg])) {
        $saida[$row->nomreg] = array(floatval($row->valven));
    } else {
        array_push($saida[$row->nomreg], floatval($row->valven));
    }

    $arrayFinal[$row->nomreg] = [
        'name' => $row->nomreg,
        'data' => $saida[$row->nomreg]
    ];
}
print_r($arrayFinal);

and object to the result:

Array
(
[PR] => Array
    (
        [name] => PR
        [data] => Array
            (
                [0] => 6835.7
            )

    )

[SC] => Array
    (
        [name] => SC
        [data] => Array
            (
                [0] => 3129
                [1] => 346.91
            )

    )

)

So far beauty, my doubt is the following, how to pass the value 0 in the [date], when there is no value? To stay as follows:

Array
(
[PR] => Array
    (
        [name] => PR
        [data] => Array
            (
                [0] => 6835.7
                [1] => 0
            )

    )

[SC] => Array
    (
        [name] => SC
        [data] => Array
            (
                [0] => 3129
                [1] => 346.91
            )

    )

)

  • It has not been clear what the relationship of their grouping is, it seems to me that there have been more changes than just making a map grouping by code.

  • @Israelmerljak the initial array is the result of a bank select, after that I did the code below

  • The question is not very clear. What happens if you have 3 objects with SC and 1 PR ? What happens if you have 3 SC 2 PR and another distinct ?

2 answers

2

Having a variable with the array desired, calling it $input, you could do it this way:

$arr = array();
foreach($input as $value)
  $arr[$value->nomreg][] = isset($value->valven) ? $value->valven : 0;

Thus, its result would come out more or less as follows:

array(2) {
  ["PR"]=>
  array(1) {
    [0]=>
    int(0)
  }
  ["SC"]=>
  array(2) {
    [0]=>
    float(3129)
    [1]=>
    float(346.91)
  }
}

To access the data:

foreach($arr as $key => $value) {
  // $key irá retorna a chave/name - por exemplo "PR" e "SC"
  // $value irá retornar os valores 
}

To array generated would have a slightly different pattern than the one shown by you, but would be generated in a simpler and easier way, and still allowing you to have the same data, with easy access.

1


First Option

It was not very clear what you want, and the transformation of the original data into your "filtered" array did not seem to me exactly what you want by your description. I believe the result you seek is something like this:

Array (
    [41] => Array ( // Agrupa todos com codreg 41
        [0] => stdClass Object
        (
            [anomes] => 201601
            [codreg] => 41
            [nomreg] => PR
            [codcin] => 1
            [nomcin] => OUTROS
            [valven] => 6835.7000
            [qtdven] => 1078.8000
        )
    )
    [42] => Array ( //agrupa todos com codreg 42
        [0] => stdClass Object
        (
            [anomes] => 201601
            [codreg] => 42
            [nomreg] => SC
            [codcin] => 1
            [nomcin] => OUTROS
            [valven] => 3129.0000
            [qtdven] => 366.6200
        )

        [1] => stdClass Object
        (
            [anomes] => 201601
            [codreg] => 42
            [nomreg] => SC
            [codcin] => 2
            [nomcin] => PECAS
            [valven] => 346.9100
            [qtdven] => 73.6600
        )
    )
)

To do so you would need a function like this:

function groupByCodReg($inputArray) {
    $resultMap = [];

    foreach($inputArray as $data) {
        if(!isset($resultMap[$data->codreg])) {
            $resultMap[$data->codreg] = []; 
        }

        $resultMap[$data->codreg][] = $data;    
    }

    return $resultMap;
}

Second Option

Maybe what you want is to aggregate the values of the arrays into a common key to use in some graph. Then it would make sense what you tried to do with the data. That way the expected result would be like this:

array(2) {
    ["PR"]=> array(2) {
        [0]=> float(6835.7)
        [1]=> float(0)
    }
    ["SC"]=> array(2) {
        [0]=> float(3129)
        [1]=> float(346.91)
    }
}

For that you could use something like:

function aggregateValvenByNomreg($inputArray) {
    $resultMap = [];

    foreach($inputArray as $data) {
        if(!isset($resultMap[$data->nomreg])) {
            $resultMap[$data->nomreg] = [];
        }

        $resultMap[$data->nomreg][] = $data->valven;
    }

    // completa arrays com 0
    $maiorComprimento = getLengthier($resultMap);
    foreach($resultMap as $key => $value) {
        while(count($resultMap[$key]) < $maiorComprimento) {
            $resultMap[$key][] = 0.0;
        }
    }

    return $resultMap;
}

function getLengthier($array) {
    $max = 0;

    foreach($array as $data) {
        $length = count($data);
        if($length > $max) $max = $length;
    }

    return $max;
}

Follow a link from Repl.it with the code working for you to check. >>Here<<

Browser other questions tagged

You are not signed in. Login or sign up in order to post.