3

My array (stored in $r) currently looks like this... (3 entries with the same date in this example per day, sometimes there are more that share the same date.)

Array
(
    [0] => Array
        (
            [id] => 1
            [date_inserted] => 2020-09-06
            [marketplace] => Etsy
            [total_stickers] => 11
            [total_orders] => 8
            [total_value] => 41.62

    [1] => Array
        (
            [id] => 2
            [date_inserted] => 2020-09-06
            [marketplace] => Woo
            [total_stickers] => 2
            [total_orders] => 1
            [total_value] => 7.98
        )

    [2] => Array
        (
            [id] => 3
            [date_inserted] => 2020-09-06
            [marketplace] => eBay
            [total_stickers] => 44
            [total_orders] => 40
            [total_value] => 115.63
        )

    [3] => Array
        (
            [id] => 4
            [date_inserted] => 2020-09-07
            [marketplace] => Etsy
            [total_stickers] => 8
            [total_orders] => 4
            [total_value] => 34.92
        )

    [4] => Array
        (
            [id] => 5
            [date_inserted] => 2020-09-07
            [marketplace] => Woo
            [total_stickers] => 9
            [total_orders] => 3
            [total_value] => 52.90
        )

    [5] => Array
        (
            [id] => 6
            [date_inserted] => 2020-09-07
            [marketplace] => eBay
            [total_stickers] => 23
            [total_orders] => 21
            [total_value] => 58.03
        )

    )

I feel this would be better if the dates were the keys and the details for each date were combined, also [id] is not needed and the "marketplace" may as well be the key for the inner arrays thus my final output I would like is like this..

Array
(
    [2020-09-06] => Array (
       
            [Etsy] => Array
                (
                    [total_stickers] => 11
                    [total_orders] => 8
                    [total_value] => 41.62
                )
   
            [Woo] => Array
                (
                    [total_stickers] => 2
                    [total_orders] => 1
                    [total_value] => 7.98
                )

    
            [eBay] => Array
                (
                    [total_stickers] => 44
                    [total_orders] => 40
                    [total_value] => 115.63
                )
                        )
                        
    [2020-09-07] => Array (
       
            [Etsy] => Array
                (
                    [total_stickers] => 8
                    [total_orders] => 4
                    [total_value] => 34.92
                )
   
            [Woo] => Array
                (
                    [total_stickers] => 9
                    [total_orders] => 3
                    [total_value] => 52.90
                )

    
            [eBay] => Array
                (
                    [total_stickers] => 23
                    [total_orders] => 21
                    [total_value] => 58.03
                )
                        )                   
)

I've been looking at array_merge_recursive, also array_combine and also similar questions on here but can't seem to work out how to go about getting the results i want.

This is what I've tried (based on an answer from Lawrence Cherone)

$results = [];
foreach (array_column($r, 'date_inserted') as $bydate) {
    foreach ($r as $item) {
        $results[$bydate][$item['marketplace']] = [
            'total_orders' => $item['total_orders'],
            'total_stickers' => $item['total_stickers'],
            'total_value' => $item['total_value']
        ];
    }
}

But the result is that although the structure looks right now the data itself is the same for every day (not using the data for that day).

Here is the resulting array

Array
(
    [2020-09-06] => Array
        (
            [Etsy] => Array
                (
                    [total_orders] => 2
                    [total_stickers] => 3
                    [total_value] => 7.83
                )

            [Woo] => Array
                (
                    [total_orders] => 10
                    [total_stickers] => 20
                    [total_value] => 100.38
                )

            [eBay] => Array
                (
                    [total_orders] => 17
                    [total_stickers] => 18
                    [total_value] => 67.36
                )

        )

    [2020-09-07] => Array
        (
            [Etsy] => Array
                (
                    [total_orders] => 2
                    [total_stickers] => 3
                    [total_value] => 7.83
                )

            [Woo] => Array
                (
                    [total_orders] => 10
                    [total_stickers] => 20
                    [total_value] => 100.38
                )

            [eBay] => Array
                (
                    [total_orders] => 17
                    [total_stickers] => 18
                    [total_value] => 67.36
                )

        )
)

I now need to get it it show the correct data for the day.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Glen Keybit
  • 296
  • 2
  • 15
  • 1
    Can you show what you have tried, even if it doesn't work – Lawrence Cherone Sep 10 '20 at 16:04
  • 1
    Does this answer your question? [How to group subarrays by a column value?](https://stackoverflow.com/questions/12706359/how-to-group-subarrays-by-a-column-value) – floGalen Sep 10 '20 at 16:05
  • @LawrenceCherone I have updated the OP, your answer nearly solves my issue but now i have the problem that its shows all days values as the same (when they are not) – Glen Keybit Sep 10 '20 at 16:31
  • Related: [Group 2d array data by two columns then sum a third column to create a 3d array](https://stackoverflow.com/q/75514138/2943403) – mickmackusa May 15 '23 at 21:25

2 Answers2

1

Try this, use array_column to pick out the dates, loop over them, then use array_filter to filter only the items with the date, then add the item to the array using the marketplace as the key.

<?php
$data = [
    ['id' => 1, 'date_inserted' => '2020-09-06', 'marketplace' => 'Etsy', 'total_stickers' => 11, 'total_orders' => 8, 'total_value' => 41.619999999999997],
    ['id' => 2, 'date_inserted' => '2020-09-06', 'marketplace' => 'Woo', 'total_stickers' => 2, 'total_orders' => 1, 'total_value' => 7.9800000000000004],
    ['id' => 3, 'date_inserted' => '2020-09-06', 'marketplace' => 'eBay', 'total_stickers' => 44, 'total_orders' => 40, 'total_value' => 115.63],
    ['id' => 4, 'date_inserted' => '2020-09-07', 'marketplace' => 'Etsy', 'total_stickers' => 8, 'total_orders' => 4, 'total_value' => 34.920000000000002],
    ['id' => 5, 'date_inserted' => '2020-09-07', 'marketplace' => 'Woo', 'total_stickers' => 9, 'total_orders' => 3, 'total_value' => '52.90'],
    ['id' => 6, 'date_inserted' => '2020-09-07', 'marketplace' => 'eBay', 'total_stickers' => 23, 'total_orders' => 21, 'total_value' => 58.030000000000001]
];

$result = [];
foreach (array_column($data, 'date_inserted') as $date) {
    foreach (array_filter($data, function($v) use ($date) { 
        return $v['date_inserted'] === $date; 
    }) as $item) {
        $result[$date][$item['marketplace']] = [
            'id' => $item['id'],
            'total_stickers' => $item['total_stickers'],
            'total_orders' => $item['total_orders'],
            'total_value' => $item['total_value']
        ];
    }
}

print_r($result);

Result:

Array
(
    [2020-09-06] => Array
        (
            [Etsy] => Array
                (
                    [id] => 1
                    [total_stickers] => 11
                    [total_orders] => 8
                    [total_value] => 41.62
                )

            [Woo] => Array
                (
                    [id] => 2
                    [total_stickers] => 2
                    [total_orders] => 1
                    [total_value] => 7.98
                )

            [eBay] => Array
                (
                    [id] => 3
                    [total_stickers] => 44
                    [total_orders] => 40
                    [total_value] => 115.63
                )

        )

    [2020-09-07] => Array
        (
            [Etsy] => Array
                (
                    [id] => 4
                    [total_stickers] => 8
                    [total_orders] => 4
                    [total_value] => 34.92
                )

            [Woo] => Array
                (
                    [id] => 5
                    [total_stickers] => 9
                    [total_orders] => 3
                    [total_value] => 52.90
                )

            [eBay] => Array
                (
                    [id] => 6
                    [total_stickers] => 23
                    [total_orders] => 21
                    [total_value] => 58.03
                )

        )

)

https://3v4l.org/QnHQf

Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
0

Restructuring your 2d array into a 3d array is simply done with 1 loop. Just pull the level identifiers out of each row and use them as the new level keys.

Code: (Demo)

$result = [];
foreach ($array as $row) {
    $level1 = $row['date_inserted'];
    $level2 = $row['marketplace'];
    unset($row['date_inserted'], $row['marketplace']);
    $result[$level1][$level2] = $row;
}
var_export($result);

Or with array_splice(): (Demo)

$result = [];
foreach ($array as $row) {
    ['date_inserted' => $level1, 'marketplace' => $level2] = array_splice($row, 1, 2);
    $result[$level1][$level2] = $row;
}
var_export($result);
mickmackusa
  • 43,625
  • 12
  • 83
  • 136