skip to Main Content

It’s weird how simple things like these I cannot find about php on the internet. Without further ado, how do I find an element inside an array that already has a string index, with a position?

For example:

$array = ["apple"=>"red","raspberry"=>"blue","green","yellow"] // As you can see this is a mixed array
for($i=0;$i<=count($array);$i++){
   var_dump(getelementfrompos($array,$i)) // pseudocode
}
// output

array(2) => {
   [key] => string(5) "apple";
   [value] => string(3) "red"
}

array(2) => {
   [key] => string(9) "raspberry";
   [value] => string(4) "blue"
}

array(2) => {
   [key] => integer(2);
   [value] => string(5) "green"
}

array(2) => {
   [key] => integer(3);
   [value] => string(6) "yellow"
}

DUMBED DOWN VERSION:

$array = ["apple"=>"red"]
getkeyfrompos($array,0) // returns -> "apple"

How do I find an element inside an array that already has a string index, with a position, as if it was an element with a numerical index instead?

3

Answers


  1. Use array_keys() to get all the keys of the array, then index into that.

    function getkeyfrompos($array, $index) {
        return array_keys($array)[$index];
    }
    
    function getelementfrompos($array, $index) {
        return $array[getkeyfrompos($array, $index)];
    }
    
    Login or Signup to reply.
  2. I’m not entirely sure why you would want to do what you’re asking, you could use array_values and then do an array_search on the value but this would not work well for duplicate values.

    Perhaps, this is where you could just create a wrapper. Rather than access properties of your array with [0] you could access the object property with ->{0}.

    For example, a wrapper like this:

    class IndxedArrayWrapper
    {
        private object $properties;
        
        public function __construct(array $properties)
        {
            $this->properties = (object) [];
            
            array_walk($properties, fn($key, $value) => $this->__set($key, $value));
        }
        
        public function __get(string|int $index): mixed
        {
            return $this->properties?->{$index} ?? null;
        }
        
        public function __set(string|int $key, mixed $value): void
        {
            $this->properties->{count((array) $this->properties)} = ['key' => $key, 'value' => $value];
        }
    }
    

    Could be used like this:

    $myArrayWrapper = (new IndxedArrayWrapper([
        'apple' => 'red',
        'bananna' => 'yellow'
    ]));
    
    // apple, red
    ['key' => $fruit, 'value' => $colour] = $myArrayWrapper->{0};
    
    // bannna, yellow
    ['key' => $fruit, 'value' => $colour] = $myArrayWrapper->{1};
    

    You can see an example working over on 3v4l.org but this seems extremely overkill. Forgive me if I’ve mistaken what your intent is but I hope this helps.


    Further reading:

    Login or Signup to reply.
  3. Use array_keys().
    Your expectations were not completely clear so,
    in my solution I assume that if the original
    array element did not have a key, I will return NULL.

    class Temp
    {
        protected $initialArray;
        protected $keys;
    
        /**
         * Execute the console command.
         *
         * @return int
         */
        public function handle()
        {
            $this->ingest(["apple"=>"red","raspberry"=>"blue","green","yellow"]); // As you can see this is a mixed array
            
    
            for ( $i=0; $i < $this->count(); $i++ ) {
                var_dump($this->getelementfrompos($i)); // pseudocode
            }
            return 0;
        }
    
        protected function count() : int
        {
            return count($this->array);
        }
        /**
         * returns key of array element.
         * returns null if the original array element had no key.
         */
        protected function getelementfrompos(int $x) {
            if ( $x < 0 || $x >= $this->count() ) {
                throw new Exception("index {$x} out of bounds");
            }
            // Adjust to suit
            if ( ! is_string($this->keys[$x]) || is_numeric($this->keys[$x]) ) {
                return null;
            }
            return $this->keys[$x];
        }
    
        protected function ingest(array $array)
        {
            $this->initialArray = $array;
            $this->keys = array_keys($this->initialArray);
        }
    }
    

    Output

    string(5) "apple"
    string(9) "raspberry"
    NULL
    NULL
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search