0

I have a PHP array that looks like this...

$array = [

    'item1' => [
        [
            'productCount' => '3',
            'value' => 'red',
        ],
        [
            'productCount' => '3',
            'value' => 'green',
        ],
        [
            'productCount' => '3',
            'value' => 'green',
        ]
    ],

    'item2' => [
        [
            'productCount' => '1',
            'value' => 'purple',
        ]
    ],

];

I am trying to parse it so it looks like this...

Array
(
    [item1] => Array
        (
            [productCount] => 3
            [red] => 1
            [green] => 2
        )
    [item1] => Array
        (
            [productCount] => 1
            [purple] => 1
        )
)

I have this so far....

$finalArray = array();

foreach ($array as $key => $arrayItem) {

    $finalArray[$key] = $arrayItem['productCount'];

    $valueCount = count($arrayItem['productCount']);

    $finalArray[$key] = $valueCount;

}

I know this isn't much but I am stuck at this point. How do I process the values and count them in the new array?

2
  • You are currently only looping over the first level of your array. You either need to explicitly loop the second level as well, or you use array_values to extract only the content under the value keys on that level, so that you can then count how many times each value occurs using array_count_values Commented Jan 27, 2020 at 11:28
  • In you reqquirement I found the index item1 two time, it is not possible to make that , Same index name will get overwritten Commented Jan 27, 2020 at 11:28

2 Answers 2

1

This code will give you the results you want. It loops over the upper level array to get the keys and productCount values for the new array. Then it loops over the second level arrays to get the counts of each value:

$output = array();
foreach ($array as $key => $items) {
    $output[$key] = array('productCount' => $items[0]['productCount']);
    foreach ($items as $item) {
        $value = $item['value'];
        $output[$key][$value] = ($output[$key][$value] ?? 0) + 1;
    }
}
print_r($output);

The inner loop can be written more concisely using array_column and array_count_values:

$output = array();
foreach ($array as $key => $items) {
    $output[$key] = array_merge(array('productCount' => $items[0]['productCount']),
                                array_count_values(array_column($items, 'value')));
}
print_r($output);

In both cases the output is:

Array
(
    [item1] => Array
        (
            [productCount] => 3
            [red] => 1
            [green] => 2
        )
    [item2] => Array
        (
            [productCount] => 1
            [purple] => 1
        )
)

Demo on 3v4l.org

Sign up to request clarification or add additional context in comments.

Comments

1

For dynamic get all result use two times foreach loops

$array = [
    'item1' => [
        [
            'productCount' => '3',
            'value' => 'red',
        ],
        [
            'productCount' => '3',
            'value' => 'green',
        ],
        [
            'productCount' => '3',
            'value' => 'green',
        ]
    ],
    'item2' => [
        [
            'productCount' => '1',
            'value' => 'purple',
        ]
    ],
];
$new_array = $final_array = array();
foreach ($array as $key => $arrayItem) {
        foreach($arrayItem as $sub_key=>$second_item){
            $new_array[$key]['productCount'] = $second_item['productCount'];             
            $new_array[$key][$second_item['value']][] =$second_item['value'];           
        }
}
foreach ($new_array as $key => $value) {
        foreach($value as $sub_key =>$sub_value){
            $final_array[$key][$sub_key] = (is_array($sub_value))?count($sub_value):$sub_value;
        }
}
print_r($final_array);exit;

Output

Array
(
    [item1] => Array
        (
            [productCount] => 3
            [red] => 1
            [green] => 2
        )

    [item2] => Array
        (
            [productCount] => 1
            [purple] => 1
        )

)

Hope this is helpful to you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.