0

I wanna know how to iterate an array to count elements in PHP, I've trying next,

foreach ($items as $item) {
                $tm[$item->provider->name] = [];
                foreach ($items as $item) {
                    $tm[$item->provider->name][$item->product->brand->name] = isset($tm[$item->provider->name][$item->product->brand->name]) ? $tm[$item->provider->name][$item->product->brand->name] + 1 : $tm[$item->provider->name][$item->product->brand->name] = 1;
                }
            }

But I get a wrong result, I get an array but I get a very high number count as if iterated many timesmany times

The structure of the array is as follows

[{
    "id": 1,
    "product": {
        "id": 1,
        "brand": {
            "id": 1,
            "name": "iphone"
        }
    },
    "provider": {
        "id": 1,
        "name": "at&t"
    }
},
{
    "id": 2,
    "product": {
        "id": 2,
        "brand": {
            "id": 2,
            "name": "iphone"
        }
    },
    "provider": {
        "id": 1,
        "name": "at&t"
    }
},
{
    "id": 3,
    "product": {
        "id": 3,
        "brand": {
            "id": 3,
            "name": "iphone"
        }
    },
    "provider": {
        "id": 1,
        "name": "t-mobile"
    }
}]
plasticheart
  • 57
  • 1
  • 6
  • 1
    Your code does a lot of things wrong, the two most glaring errors are a) that you iterate over the array twice, nested - i.e you are doing squared more iteration than needed; B) you use a trinary as the expression to assign to the field, but the right side of the trinary is also an assignment?! – Guss Oct 15 '22 at 00:38
  • Somewhat related: [Count unique rows of data based on the values in two columns](https://stackoverflow.com/q/42182686/2943403) Also related: [Count values based on multiple key values in php](https://stackoverflow.com/q/39034047/2943403), and [Count entries grouped by id and month from denormalized database](https://stackoverflow.com/q/71141553/2943403) – mickmackusa Oct 15 '22 at 08:41

2 Answers2

1

IIUC, you are trying to count the product->brand->name values for each provider->name. You can do that using this code:

$tm = array();
foreach ($items as $item) {
    $product = $item->product->brand->name;
    $provider = $item->provider->name;
    $tm[$provider][$product] = ($tm[$provider][$product] ?? 0) + 1;
}

print_r($tm);

Output (for your sample data):

Array
(
    [at&t] => Array
        (
            [iphone] => 2
        )
    [t-mobile] => Array
        (
            [iphone] => 1
        )
)

Demo on 3v4l.org

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Nick
  • 138,499
  • 22
  • 57
  • 95
-1

From your code example you apparently want to count how many occurrences are for each "thing" in your array, otherwise count() would have probably sufficed...

Though you are doing a lot of work to pre-init the counting array - that is completely unneeded: read about auto-vivifcation.

Code like so would probably suffice (I'm not following your example code here - you'd need to work out to your needs):

$counters = [];
foreach ($items as $item)
  @$counters[$item->name][$item->model]++;
Guss
  • 30,470
  • 17
  • 104
  • 128
  • 1
    PHP is going to cry foul at the `++` applied to undeclared elements. – mickmackusa Oct 15 '22 at 05:24
  • You are right - `++` can auto-vivify unset field into an `int` but can't do an unset field to array with a field. Fortunately, `+=` does work as we need. I fixed my answer. – Guss Oct 15 '22 at 12:26
  • This answer does not appear to be fixed. The addition assignment operator also requires the variable to be declared in advance. Write yourself a 3v4l.org demo to prove it to yourself. – mickmackusa Oct 15 '22 at 12:28
  • A) @mickmackusa, give it a refresh; B) I have verified that this works in PHP 8.1 CLI. – Guss Oct 15 '22 at 12:29
  • @mickmackusa - I take it back: `++` works just as well, it just shows notices (or warnings, depending on your PHP version) about missing keys. I silenced them with `@` and it works fine. – Guss Oct 15 '22 at 12:38
  • I will not be upvoting an answer that recommends a hack like the stfu operator. Nick's answer demonstrates a professional technique. – mickmackusa Oct 15 '22 at 12:47
  • Legit opinion, I guess. – Guss Oct 15 '22 at 13:08