Getting a value from an associative array

Hi,

I have the following array:

$my_array = array(
	'key1' => array(
		'number' => 1,
	),
	'key2' => array(
		'number' => 3,
	),
	'key3 => array(
		'number' => 2,
	),
)

I want to get key1’s number value which is 1 in this sample. key1 is not a constant. Do you have an idea how to get that value?

Thanks.

Try,

$my_array[‘key1’][‘number’];

or

$my_array[‘0’][‘number’];

I can’t use

$my_array[‘key1’][‘number’];

because key1 is dynamic.

It is always the first key though. I tried

$my_array[0][‘number’];

and it doesn’t work.

You can get the first element of an array with


$first = reset( $my_array );

// or this which removes it from the original array
$first = array_shift( $my_array );

Dynamic Sure, but at some point you will be looping through this array or using the key defined in another part of your code. You can also build an array of these “unknown” keys and then loop through them.

$array_keys = array_keys($my_array);
foreach($array_keys as $key){
	echo "{$my_array[$key]['number']}<br />";
}

It’s possible to use this following syntax if you have dynamic keys:


$myArray[$key][$key2];

So yeah even if the key is dynamic you still have ways to reference it, I personally would not recommend using php native arrays for multidimensional arrays/structures, consider using object in your case.

$first = reset( $my_array );

did the job, thank you all!

Why?

The usage of multidimensional associative array suggests that the program/script is poorly designed in the very first place, can easily lead to spaghetti procedural code. A much better idea is to use composite pattern on objects/classes instead.

You can make an object nest just as convoluted as an array nest and just as hard to debug.

Arrays have their place.

Yeah arrays have their places, I never said they don’t. It’s about how some coders use two or three dimensional arrays to store information that should belong to what we call domain object/model that I don’t particularly like. If an associative array contains user information such as uid, username, password, email, ip, and birthday, why not create domain objects instead? You can either use active record or data mapper to give them useful business logic, that’s what an associative array cannot provide.

Actually I do use arrays a lot, I especially like PHP’s splfixedarray api, and use it to store some a list of constant information. However, PHP’s native arrays can be a problem, they are not even object oriented. The presence of multidimensional associative arrays is usually a bad smell that a program is not object oriented/modular as it should be, I’d only use php native arrays sparsingly.

Indeed. In fact last I knew some PHP functions return multi-dimensional arrays.

Having “cut my teeth” on BASIC I actually have less trouble following the logic of spaghetti code in a single file than I do opening several class files.

But to get back to the topic of arrays.
I’m wondering if the numeric key isn’t working because it’s an associative array?

Unless your example here was a loosely described sample of something more complex, I’m wondering why you have two levels in this array.

Wouldn’t :


$my_array = array(
	'key1' => array(
		'number' => 1,
	),
	'key2' => array(
		'number' => 3,
	),
	'key3 => array(
		'number' => 2,
	),
)

Be the same as:



$my_array = array('key1'=>1,'key2'=>3,'key3'=>2);


and since you say in this example that the item you want is always the first one, I’m gonna take a WAG here and assume that for some other purpose you’re always going to want the 2nd item for that use, and the 3rd item for some other usage. So, that means we can reduce your array even further:



$my_array = array(1,3,2);


Which means you can get the first element simply with $my_array[0], the second with $my_array[1] and the third as $my_array[2] with no need for a ‘known’ key value…

No ???
$

No, it’s not working because PHP arrays don’t work that way. $a[0] is not a reliable way to access the first element of an array. Take a look at the following code.


<?php

$a = array (
 '1' => 'one',
 '2' => 'two',
 '0' => 'zero'
);

echo $a['0']; // zero, as we'd expect.
echo $a[0]; // zero ?? yep, zero, even though $a['0'] is the 3rd element of the array
echo reset($a); // one.

?>

Numerical references to keys do not work reliably unless care is taken. PHP ‘arrays’ are what other languages would call dictionaries, lists, or even free form objects. Understand that and you understand that there isn’t much operative difference between $a = array() and $a = new stdClass(); Both constructs can have members arbitrarily assigned to them, sometimes to curious or disastrous effect.

PHP key types aren’t meant to be interchangeable. This sometimes happens, especially in code written for the older database drivers which will return db results with both associative and integer keys (unless commanded not to do so). If you choose to treat them that way, be prepared to be surprised as the code I jotted down about shows.

Personally I’m all for object oriented code, but there’s something to be said for list and dictionary management. To that end I heavily use the ArrayObject class and extend off of the offsetSet function to control the data that can be placed in the array when that is necessary. I prefer having the array access syntax be used to mark the difference between the data, and object settings and properties. For example, in my template class $template->template is the html file the template will use when evaluated. $template[‘template’] can be set, but whatever meaning it has will be up to the person writing the template - it has no special meaning to the class.

PHP arrays are one of the most powerful features of the language, but they are also badly misnamed as they combine several discreet data structure concepts into one. Be careful with them.

Michael,

You have created an associative array by putting quotes around your numbers for the indices. Consequently the user can’t rely on the positional order of the elements in the array. Leave off the indices when you create the elements and the order will be as one would expect since in the OP’s problem the creation order had to be known before he could do any retrieval

Run this then…


<?php

$a = array (
 1 => 'one',
 2 => 'two',
 0 => 'zero'
);

echo $a['0']; // zero.
echo $a[0]; // zero ?? yep, zero
echo reset($a); // one.
?>

As you’ll see, quoting the keys doesn’t make a bit of difference - if you declare the array elements out of order, they’ll be out of order.

Consequently the user can’t rely on the positional order of the elements in the array. Leave off the indices when you create the elements and the order will be as one would expect since in the OP’s problem the creation order had to be known before he could do any retrieval

We don’t always receive arrays in that manner. If keys aren’t specified $a[0] will hit the first element as expected. This isn’t any different from any other language. It’s when programmers mix and match the behaviors that trouble shows up, especially since PHP doesn’t really try to stop them from doing this.

Run this then:


$my_array = array(1,3,2);
echo "first element is $my_array[0]<br>";
echo "2nd element is $my_array[1]<br>";
echo "3rd element is $my_array[2]<br>";


As the OP said his retrieval was position oriented, my original example would work as shown here.

Or do this:


$my_array2[] = 1;
$my_array2[] = 3;
$my_array2[] = 2;
echo "first element is $my_array2[0]<br>";
echo "2nd element is $my_array2[1]<br>";
echo "3rd element is $my_array2[2]<br>";


Your example is irrelevant. The OP explicitly set the keys…


$my_array = array(
	'key1' => array(
		'number' => 1,
	),
	'key2' => array(
		'number' => 3,
	),
	'key3' => array(
		'number' => 2,
	),
)

When keys are explicitly set you should not rely on PHP’s internal indexing.

I think the OP needs to realize that if he doesn’t know what the key is for the first element (it’s dynamic), then why bother with a key in the first place? Just use a simple non-indexed array and always grab the first element ( [0] ) as he said he wanted to do. Why need an index?

For that matter, if he knows that the first element of his array is specifically “itemx” every time, he needs to re-consider why he even has to use an array when a variable such as $itemx would work just as well.

A very good point.

For that matter, if he knows that the first element of his array is specifically “itemx” every time, he needs to re-consider why he even has to use an array when a variable such as $itemx would work just as well.

If the items belong together there is cause for them to be in an array