Page 1 of 2
Named vs Numeric Array Indexes
Posted: Sat Aug 07, 2010 7:50 pm
by ColonelSandersLite
Out of curiosity, does anybody know why named array keys seem to be so popular in php? I *think* that php is the first language I learned which can really do this, so I always just use standard numeric keys out of habit. Is there actually any real advantage I've missed to using named keys?
Just to be sure what I'm asking is clear, why does this:
Code: Select all
$arr = array("foo" => "bar", 12 => true);
seem to be more popular than this:
Re: Named vs Numeric Array Indexes
Posted: Sat Aug 07, 2010 8:08 pm
by requinix
For one, you actually know what keys mean what.
Code: Select all
$array["title_urlsafe"] = transform($array["title"]);
Re: Named vs Numeric Array Indexes
Posted: Sat Aug 07, 2010 10:08 pm
by califdon
I think most modern programming languages have the means to do this, but they often use different names, like "hashes", "dictionaries", etc. I think PHP is just more honest and calls them all "arrays". By using a key to reference a value, regardless of what you may call it, you save several lines of programming to equate your real-world key to an index number. In the real-world, we don't often refer to things by numbers, so in this sense, my view is that PHP maps to the real-world better.
Re: Named vs Numeric Array Indexes
Posted: Sun Aug 08, 2010 12:13 am
by ColonelSandersLite
Correct me if I'm wrong here, but one serious disadvantage of naming the keys is that it sometimes precludes the ability to easily loop through them right? In other words, this will work with a numeric index but not a named index:
Code: Select all
// not tested syntactically accurate, but you'll get the idea
$myArray= array(someValue, someValue, someValue, ...);
for ($i = 0; $i < count ($images); $i++)
{
echo "$myArray[$i]<br>\n";
};
As far as knowing what's in the array goes, you should already know this! It's spelled out clearly when you load the array in the first place. For example:
Code: Select all
// not tested syntactically accurate, but you'll get the idea
$images = array();
// your structure is *right here*
$query = "SELECT `Path`, `SizeX`, `SizeY`, `AltText` FROM `Images` WHERE etc etc etc";
// for the purposes of abbreviation, assume that the query was run and the results fetched here. The result being:
// [[Path, SizeX, SizeY, AltText], [Path, SizeX, SizeY, AltText], ...]
for ($i = 0; $i < count ($images); $i++)
{
echo "<img src=\"{$myArray[$i][0]}\" w=\"{$myArray[$i][1]}\" h=\"{$myArray[$i][2]}\" alt=\"{$myArray[$i][3]}\"><br>";
};
// I guess this is just as valid, though it precludes the possibilitly of doing special things on specific indexes. I guess a counter can work around it though:
forEach $images as $image
{
echo "<img src=\"$image[Path]\" w=\"$image[SizeX]\" h=\"$image[SizeY]\" alt=\"$image[AltText]\"><br>";
};
As you can see, I'm not saving several lines of code by using named indexes at all. If I wanted to say, do a line break after every 4th image, I would have to add 2 lines of code to initialize a counter and maintain it (the comparison would be the same in both loops though).
Meh, I just don't really see the point. Maybe I'm just too used to numeric indexes since my first 5 (or more) programming languages used them (at least nearly) exclusively.
Re: Named vs Numeric Array Indexes
Posted: Sun Aug 08, 2010 2:12 am
by requinix
Code: Select all
echo "<img src=\"{$myArray[$i][0]}\" w=\"{$myArray[$i][1]}\" h=\"{$myArray[$i][2]}\" alt=\"{$myArray[$i][3]}\"><br>";
Looking at that (and putting aside the HTML markup itself) I have no clue what's in $myArray. The first dimension is no doubt a straight list of items, but the second dimension is totally vague. What's #3? Alt text? Image title? Name associated with the image? Static text?
ColonelSandersLite wrote:As far as knowing what's in the array goes, you should already know this! It's spelled out clearly when you load the array in the first place.
And what if the array was populated somewhere not close by? Another function? Another file entirely? If I know that $myArray has items from a database table then I immediately know what the fields are. With indexes I have to find where the array was generated and see which order the fields were chosen in. If you SELECT A,B,C you cannot easily change the fields without going through every single file looking for whether that array gets used. Should you use string keys you can add or move fields without caring about anything.
If you want the cut-and-dried version,
1. Associative arrays can be easily converted to indexed arrays with
array_values. array_combine can go the other direction but it's messier.
2. Re "the ability to easily loop through them":
foreach.
When appropriate, associative arrays are always more powerful than indexed arrays.
Also, why not skip the whole discussion and just use functions like
mysql_fetch_array that satisfy everybody?
Re: Named vs Numeric Array Indexes
Posted: Sun Aug 08, 2010 1:10 pm
by califdon
tasairis wrote:Also, why not skip the whole discussion and just use functions like
mysql_fetch_row that satisfy everybody?
Yes, that is my inclination, too. PHP provides lots of alternatives, nobody is going to make you use associative arrays if you believe you can do better with numeric indexed arrarys. Use whichever you want.
Re: Named vs Numeric Array Indexes
Posted: Sun Aug 08, 2010 2:50 pm
by ColonelSandersLite
tasairis wrote:Code: Select all
echo "<img src=\"{$myArray[$i][0]}\" w=\"{$myArray[$i][1]}\" h=\"{$myArray[$i][2]}\" alt=\"{$myArray[$i][3]}\"><br>";
Looking at that (and putting aside the HTML markup itself) I have no clue what's in $myArray. The first dimension is no doubt a straight list of items, but the second dimension is totally vague. What's #3? Alt text? Image title? Name associated with the image? Static text?
Simple, "`AltText` FROM `Images`" as defined in line 6.
tasairis wrote:And what if the array was populated somewhere not close by? Another function? Another file entirely? If I know that $myArray has items from a database table then I immediately know what the fields are. With indexes I have to find where the array was generated and see which order the fields were chosen in.
If you don't know the return format of your function, you're in trouble if you don't find out regardless. In the case of both, you still have to look it up when you're writing fresh code or debugging something with the array. I guess with named indexes you can print_r the array to find out, but I honestly don't find that to be more convenient than just looking up a few lines.
tasairis wrote:Should you use string keys you can add or move fields without caring about anything.
I can see this point in some instances, but it's not quite true in all cases. It's not hard to imagine loops and such, that are there to process an array, getting thrown by unexpected values regardless of how it's indexed. This sounds to me like it's the highway to bug city.
tasairis wrote:When appropriate, associative arrays are always more powerful than indexed arrays.
This is exactly what I want to know here. In what tangible way are they more powerful? Of course I'm already using numeric indexes, such as is returned by mysql_fetch_row(), but what I want to know, is whether or not there is any real reason I should change this practice. As long as you keep the spaghetti code to a minimum, it's just not hard to look up and see how the array was indexed, or check the return value of the function you got it from. I also maintain that numeric arrays are less prone to having a typo in the key as well. I would *really* like to see some example of something a named key can do which a numeric key cannot, but I really doubt such a thing exists.
Re: Named vs Numeric Array Indexes
Posted: Mon Aug 09, 2010 2:33 am
by Weirdan
Simple and expressive:
Code: Select all
if ($config['someFeature']['enabled']) {
// do something
}
Re: Named vs Numeric Array Indexes
Posted: Tue Aug 10, 2010 12:06 pm
by ColonelSandersLite
Which is no different than:
Code: Select all
if ($config[X]['enabled']) {
// do something
}
Or if you want to not have to worry about the order of a config file changing, this is the way I do it:
Code: Select all
if ($cfg_someFeature == 'enabled') {
// do something
}
Re: Named vs Numeric Array Indexes
Posted: Tue Aug 10, 2010 12:15 pm
by shawngoldw
associative keys are just simpler to read, and understand quickly without having to reference other parts fo your code. They are much more descriptive.
Although you can't iterate through them with a traditional for loop, you can use a foreach loop.
Code: Select all
foreach ($array as $key => $value)
{
// code...
}
Just as easy to work with, but not quite as flexible as a for loop.
Use what you're comfortable with.
Shawn
Re: Named vs Numeric Array Indexes
Posted: Tue Aug 10, 2010 12:44 pm
by ColonelSandersLite
That's probably just about the most concise answer possible man.

Re:
Posted: Tue Aug 10, 2010 4:19 pm
by VladSun
Well, people familiar with C/C++ [] operator concept know that (e.g.) [2] means:
addressOf(variable) + 2*(sizeOf(variableType)) ...
it has NOTHING to do with hash/dictionary types... it's simple
Hashes (
Perl has better interpretation of "numeric" and "associative" arrays, IMHO) are much more complex, so the straight answer to the OP subject question (
Named vs Numeric Array Indexes ) is "numeric arrays win"

Re: Named vs Numeric Array Indexes
Posted: Tue Aug 10, 2010 4:23 pm
by VladSun
Weirdan wrote:Simple and expressive:
Code: Select all
if ($config['someFeature']['enabled']) {
// do something
}
Code: Select all
define('someFeature', 0);
define('enabled', 1);
define('disabled', 0);
if ($config[someFeature][enabled]) {
// do something
}
I think it's more readable

(it's even without E_NOTICE raised

)
It's even less error prone ... which I think is the most important ...
Re: Named vs Numeric Array Indexes
Posted: Tue Aug 10, 2010 5:32 pm
by Weirdan
VladSun wrote:it's even without E_NOTICE raised

)
What's with E_NOTICE? My original code wouldn't raise any notices, unless the config branch happened to be undefined. But in this case yours would throw a notice as well.
It's even less error prone ... which I think is the most important ...
You do realize that it would require to create lots of constants for even moderately complex adhoc config structure, right? And you wouldn't be able to easily inspect parts of the structure with built in tools like var_dump() or print_r(). And there's high chance of collisions when those constants are reused on different levels.
If your point was that it's possible to avoid hashes most of the time - yes, I agree. Is it worthwhile goal to pursuit - that I doubt.
Re: Named vs Numeric Array Indexes
Posted: Wed Aug 11, 2010 4:06 am
by ColonelSandersLite
Weirdan wrote:It's even less error prone ... which I think is the most important ...
You do realize that it would require to create lots of constants
I would tend to agree there. It would just be much much easier to ditch arrays and use straight variable names instead of doing that.
EX:
Code: Select all
// config file
$cfg_someFeature = 0;
$cfg_someOtherFeature = 1;
$cfg_someDifferentFeature = 1;
$cfg_aFeature = 0;
$cfg_something = 1;
$cfg_youGetTheIdea = ?;
//test you use elsewhere
if ($cfg_someFeature == 1)
{
// dosomething
};
Doing this is probably less typing than using an array with names indexes anyways. Meh, maybe about the same, depending on how you do it. Still, less special characters which, at least for me, is faster to code.