0

I am using Laravel 10 with Livewire v3. I have a method that accepts array as one of the parameter. If the parameter is just an array then the method will behave differently, if the parameter is associative array then the method will use the keys and values both and behave differently. The passed associative array can have sequential keys as shown in the code below.

Below is the extracted logic and I don't want it to detect $associative_sequential array as a sequential array. What do I need to add/change for that to happen because I don't want $sequential array to be identified as associative array either.

public function doSomething($passedArray) {
    if (is_array($passedArray)) {
        if ($passedArray == array_values($passedArray)) {
            echo "The passed array is a sequential array.\n";
        } elseif (array_keys($passedArray) == array_filter(array_keys($passedArray), 'is_int')) {
            echo "The passed array is an associative array with integer keys.\n";
        } else {
            echo "The passed array is an associative array with non-integer keys.\n";
        }
    } else {
        echo "The passed variable is not an array.\n";
    }
}

$sequential = array("apple", "banana", "cherry");
$associative_sequential = array(0 => "apple", 1 => "banana", 2 => "cherry");
$associative_non_sequential = array(10 => "apple", 20 => "banana", 25 => "cherry");
$strict_associative = array("fruit1" => "apple", "fruit2" => "banana", "fruit3" => "cherry");

doSomething($sequential);
doSomething($associative_sequential);
doSomething($associative_non_sequential);
doSomething($strict_associative);

Outputs:

// This is what I am getting
The passed array is a sequential array.
The passed array is a sequential array.
The passed array is an associative array with integer keys.
The passed array is an associative array with non-integer keys.

// This is what I want to happen
The passed array is a sequential array.
The passed array is an associative array with integer keys.
The passed array is an associative array with integer keys.
The passed array is an associative array with non-integer keys.
5
  • 3
    ['apple', 'banana', 'cherry'] and [0 => 'apple', 1 => 'banana', 2 => 'cherry'] are both sequential (indexed) arrays, and are actually identical (if you store them in variables and compare them, you'd see they are equivalent, $sequential == $associative_sequential is true). If you omit the 0 => ..., it still uses those indices, you just don't seem them until you access/view the array. And for accessing the first element of an array, its $arr[0]. It's only when you have non-sequential, non-numeric, etc. keys that you have a non-sequential (associative) array. Your output is correct. Commented Dec 12, 2023 at 16:43
  • 1
    If you're a visual person, this image should help. Note how after defining the variables, the console outputs them exactly the same. For the other arrays, the console explicitly shows the indices. Commented Dec 12, 2023 at 16:49
  • 1
    So the TL;DR, if you want the output you're suggesting, simply change your code to $associative_sequential = array(1 => "apple", 2 => "banana", 3 => "cherry"); (I think) Commented Dec 12, 2023 at 16:51
  • @TimLewis Does that mean array(0 => "apple", 1 => "banana", 2 => "cherry") and array(1 => "apple", 2 => "banana", 3 => "cherry") are different type of array in the sense that one is sequential by implementation and other associative as it does not start with 0. I assume in second array $arr[0] will not work, is that the case ? Commented Dec 12, 2023 at 16:53
  • 1
    That's correct. An Indexed Array is one that goes from 0, 1, 2, ..., Infinity. An Associative Array can have any other keys; sequential (as long as it doesn't start from 0, or skips indices) like 1, 2, 4, 5, 9, ... or 0, 2, 4, ..., etc, reversed or non-sequential, like 2, 1, 0 or 2, 0, 1, etc., non-numeric, like a, b, c, etc. [0, 1, 2] and [0 => 0, 1 => 1, 2 => 2] are equivalent, one simply omits the keys since they are the defaults. And yes, $arr[0] will fail for [1 => 'apple', 2 => 'banana', 3 => 'cherry'], since there is no 0 key. Commented Dec 12, 2023 at 16:57

1 Answer 1

1

PHP's "array" type is slightly unusual in its flexibility. Depending on your point of view, it's either very powerful, or very muddled.

Every array in PHP tracks, among other things:

  • The order of its items
  • A unique string or integer key for every item
  • The highest integer key currently used

This is easiest to see when you explicitly list both keys and values. The following are all different array values:

$a = [0 => 'a', 1 => 'b'];
$b = [1 => 'a', 2 => 'b']; // same value, same order, but different keys
$c = [1 => 'a', 0 => 'b']; // same keys and values, in a different order

If you don't specify the key explicitly, PHP automatically assigns the next unused integer. This is most obvious when appending items to a list:

$a = [];
$a[] = 'a';
$a[] = 'b';
var_export($a);
// array ( 0 => 'a', 1 => 'b', )

The first element in the empty list was given key 0, but if there were existing items, PHP would start at the highest:

$a = [42 => 'answer'];
$a[] = 'a';
var_export($a);
// array ( 42 => 'answer', 43 => 'a', )

$a = [-100 => 'answer'];
$a[] = 'a';
var_export($a);
// array ( -100 => 'answer', -99 => 'a', )

$a = [5 => 'five', 3 => 'three'];
$a[] = 'a';
var_export($a);
// array ( 5 => 'five', 3 => 'three', 6 => 'a', )

The same thing happens when you write an array literal without keys:

$a = ['a', 'b'];
var_export($a);
// array ( 0 => 'a', 1 => 'b', )

You can even specify some keys, and let PHP choose others:

$a = [0 => 'a', 'b'];
var_export($a);
// array ( 0 => 'a', 1 => 'b', )

$a = ['a', 1 => 'b'];
var_export($a);
// array ( 0 => 'a', 1 => 'b', )

So, in short, your function is working correctly: array("apple", "banana", "cherry") and array(0 => "apple", 1 => "banana", 2 => "cherry") are just different ways of writing the same thing.

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

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.