William
William

Reputation: 1030

Why is this array count returning 1 instead of 2?

Why is this array count returning 1 instead of 2?

Shouldn't it return 2?

$join = [
   'JOIN' => ['coins','users.id','user_id'],
   'JOIN' => ['coins','users.id','user_id']
];

echo count($join);

Upvotes: 0

Views: 695

Answers (4)

SOFe
SOFe

Reputation: 8214

You are creating an associative array, which means that each element is associated to one unique key. Therefore, in an array, each key can only appear once. A key appearing twice means that the value will be overwritten.

If you try to var_dump your array, it would have this output:

array(1) {
  ["JOIN"]=>
  array(3) {
    [0]=>
    string(5) "coins"
    [1]=>
    string(8) "users.id"
    [2]=>
    string(7) "user_id"
  }
}

As seen from this result, only one line exists.

If you need to have 'JOIN' in every element, maybe you want to change your array structure into this:

$join = [
   ['JOIN' => ['coins','users.id','user_id']],
   ['JOIN' => ['coins','users.id','user_id']]
];

This will carry the information 'JOIN' in every element. However, I cannot imagine why you would need such a thing.

Instead, maybe you want to have multiple elements under the 'JOIN key:

$join = [
    'JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id']
    ]
];

As per your comments, maybe you eventually want to have a structure like this:

$join = [
    'JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id'],
    ],
    'INNER JOIN' => [
        ['coins','users.id','user_id'],
        ['coins','users.id','user_id'],
    ]
];

According to your comments, it might be more desirable if you do this through object-oriented programming instead:

class Join{
    const JOIN = 0;
    const INNER_JOIN = 1;
    // we are using constants to prevent bugs caused by typos
    public $type;
    public $coins;
    public $usersDotId; // I don't really know what you are trying to do here
    public $userId;
}

Then you can use it like this:

$joins = [];

$join = new Join();
$join->type = Join::INNER_JOIN;
$join->coins = "some_value";
$join->usersDotId = "some_value";
$join->userId = "some_value";
$joins[] = $id;

Upvotes: 3

Don't Panic
Don't Panic

Reputation: 41810

Without addressing the more specific problem that appeared in the comments, and acknowledging that you've already accepted an answer that works for your purposes, here is a more theoretical explanation for why you can't have two of the same key. This may be not be useful for you, but hopefully it could help someone who does not intuitively grasp this concept.

Regardless of whether you assign your own string keys ($array = ['key' => 'value'];), assign your own integer keys ($array = [42 => 'the answer'];), or let PHP automatically assign integer keys ($array[] = 'something';), the keys must be unique.

According to the PHP manual for arrays:

An array in PHP is actually an ordered map. A map is a type that associates values to keys.

Most programming languages have something like this. This association of values to keys means that by definition, keys must be unique. If a language allowed you to create a "map" with multiple identical keys pointing to different values, looking up a value by key would be impossible (or at least would produce ambiguous results), so the map would be fairly useless.

PHP will let you write things like:

$example = [
   'a' => 1,
   'b' => 2,
   'a' => 3,
];
var_dump($example);

without giving any errors, but the result of that will be:

array (size=2)
  'a' => int 3
  'b' => int 2

where 'a' => 3 has overwritten the previously defined value of the 'a' key. This allows the map to continue to work, so that $example['a'] will always yield the same value. If you actually could have

array (size=3)
  'a' => int 1
  'b' => int 2
  'a' => int 3

Then what would be the result of $example['a']? Any defined behavior (first instance of 'a', etc.) would mean that some values of 'a' would be inaccessible.

Upvotes: 2

Ravi Mule
Ravi Mule

Reputation: 404

Because you are using same array key to both the element

try this,

<?php
$join = [
   'JOIN1' => ['coins','users.id','user_id'],
   'JOIN2' => ['coins','users.id','user_id']
];
echo count($join);
?>

Or with same key try following

$join = [
   ['JOIN' => ['coins','users.id','user_id']],
   ['JOIN' => ['coins','users.id','user_id']]
];

Upvotes: 0

Martin
Martin

Reputation: 22760

$join = [
   'JOIN' => ['coins','users.id','user_id'],
   'JOIN' => ['coins','users.id','user_id']
];

echo count($join);

how may I modify this array to have 2 keys, without changing the key name?

In order to not need to change this key name, make JOIN an array of numeric values so structurally you want:

array:

 ----> [Join] :
          \---> [0] 
                 \--->   coins
                 |--->   users.id
                 |--->   user.id

This can be achieved with this syntax (clarified for understanding):

$join = [
   'JOIN' => [0] => ['coins','users.id','user_id'],
             [1] => ['coins','users.id','user_id']
];

(simplified for ease):

$join = [
       'JOIN' =>  ['coins','users.id','user_id'],
                  ['coins','users.id','user_id']
    ];

gives you a $join array with a count of 1, which contains (the one) an array with a count of 2, each of those containing 3 elements.

Upvotes: 2

Related Questions