Need help with Arrays

How many Arrays are in the sample data below…


ID	GROUP		ALBUM			SONG
1	Led Zeppelin	Led Zeppelin III	Friends
						Gallows Pole
						That's the Way

1	Led Zeppelin	Houses of the Holy	Over the Hills and Far Away
						D'yer Mak'er
						The Ocean

2	Cream		Disraeli Gears		Strange Brew
						SWLABR

Debbie

Two per row where the index 2 is an array of songs

One row of the array is like


$music = array('GROUP' => 'Led Zeppelin', 'ALBUM' => 'Led Zeppelin III', 'SONGS' => array("Friends", "Gallows Pole", "That's the Way"));

Each row shown in your example would be formatted this same way.

Steve

However, if this was returned by a database you would not get this structure and then this structure is one array per row. The multiple values in the songs column would be a bad thing if this was the case.

A database would likely return a result set like:

[TABLE=“class: grid, width: 500”]
[TR]
[TD]ID[/TD]
[TD] GROUP [/TD]
[TD] ALBUM[/TD]
[TD]SONG[/TD]
[/TR]
[TR]
[TD]1[/TD]
[TD]Led Zeppelin[/TD]
[TD] Led Zeppelin III [/TD]
[TD]Friends [/TD]
[/TR]
[TR]
[TD]2[/TD]
[TD]Led Zeppelin[/TD]
[TD] Led Zeppelin III [/TD]
[TD]Gallows Pole [/TD]
[/TR]
[TR]
[TD]3[/TD]
[TD]Led Zeppelin[/TD]
[TD] Led Zeppelin III [/TD]
[TD] That’s the Way[/TD]
[/TR]
[/TABLE]

This would probable be better served with 4 tables Groups, Albums, Songs, and Groups2Albums2Songs (as g2a2s). Then the following rows in the g2a2s table might be;

[TABLE=“class: grid, width: 500”]
[TR]
[TD]ID[/TD]
[TD] group_id [/TD]
[TD] album_id[/TD]
[TD]song_id[/TD]
[/TR]
[TR]
[TD]1[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]1[/TD]
[/TR]
[TR]
[TD]2[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]2[/TD]
[/TR]
[TR]
[TD]3[/TD]
[TD]1[/TD]
[TD]3[/TD]
[TD]3

[/TD]
[/TR]
[/TABLE]

This is where I am getting confused…


'GROUP' => 'Led Zeppelin'
'ALBUM' => 'Led Zeppelin III'
'SONGS' => array("Friends", "Gallows Pole", "That's the Way")

'GROUP' => 'Led Zeppelin'
'ALBUM' => 'Houses of the Holy'
'SONGS' => array("Over the Hills and Far Away", "D'yer Mak'er", "The Ocean")

'GROUP' => 'Cream'
'ALBUM' => 'Disraeli Gears'
'SONGS' => array("Strange Brew", "SWLABR")

How can you have a key like ‘GROUP’ repeat 3 times?! :-/

I would have went with something like this for starters…


KEY		VALUE
0		Led Zeppelin
1		Led Zeppelin
2		Cream

Or maybe something like this…


array(
	Led Zeppelin=>array(
				Led Zeppelin III=>array(
							Friends=>3:55
							Gallows Pole=>4:58
							That's the Way=>5:38)));
array(
	Led Zeppelin=>array(
				Houses of the Holy=>array(
							Over the Hills and Far Away=>4:50
							D'yer Mak'er=>4:23
							The Ocean=>4:31)))

array(
	Cream=>array(
				Disraeli Gears=>(
							Strange Brew=>2:46
							SWLABR=>2:32)))

I guess I just think in database terms and am having a hrd time visualizing and understanding things in array terms… :frowning:

Furthermore, like a lot of things in programming, there seem to be a couple of different ways to do things, and so I never know which is the more correct way?! :-/

Am I making any sense?

Debbie

The most generic way to explain 90% of cases is that each row is a separate, associative array. Each key of the associative array is the table column name and value the column value.

But what about my long response above your last post???

Debbie

Hi DoubleDee,

To answer your first question – you technically have 1 array, which can be described as a multi-dimensional array.

A better visual representation of your array is below. As it is an array of array’s.

To answer your second question about having ‘GROUP’ repeat 3 times – each ‘GROUP’ is an associative key that is kept in a separate array. It seems to repeat, but it does not within each individual ordinal (aka record or index). If you were to repeat the ‘GROUP’ within the same ordinal of the array it would overwrite what was there before.


Array
(
    [0] => Array
        (
            [ID] => 1
            [GROUP] => Led Zeppelin
            [ALBUM] => Led Zeppelin III
            [SONGS] => Array
                (
                    [0] => Friends
                    [1] => Gallows Pole
                    [2] => That's the Way
                )

        )

    [1] => Array
        (
            [ID] => 1
            [GROUP] => Led Zeppelin
            [ALBUM] => Houses of the Holy
            [SONGS] => Array
                (
                    [0] => Over the Hills and Far Away
                    [1] => D'yer Mak'er
                    [2] => The Ocean
                )

        )

    [2] => Array
        (
            [ID] => 2
            [GROUP] => Cream
            [ALBUM] => Disraeli Gears
            [SONGS] => Array
                (
                    [0] => Strange Brew
                    [1] => SWLABR
                )

        )

)

The neat thing about array’s is that you can create them in different ways. Below is the same array written differently for the PHP code.


<?php

$music[0] = array('ID' => '1', 'GROUP' => 'Led Zeppelin', 'ALBUM' => 'Led Zeppelin III', 'SONGS' => array("Friends", "Gallows Pole", "That's the Way"));
$music[1] = array('ID' => '1', 'GROUP' => 'Led Zeppelin', 'ALBUM' => 'Houses of the Holy', 'SONGS' => array("Over the Hills and Far Away", "D'yer Mak'er", "The Ocean"));
$music[2] = array('ID' => '2', 'GROUP' => 'Cream', 'ALBUM' => 'Disraeli Gears', 'SONGS' => array("Strange Brew", "SWLABR"));

echo "<pre>";
print_r($music);
echo "</pre>";

?>

And the same array again, written differently (usually used when you want to store information from a database into an array). It is done this way to break it down into simple steps for loops.


<?php

$music[0]['ID'] = '1';
$music[0]['GROUP'] = 'Led Zeppelin';
$music[0]['ALBUM'] = 'Led Zeppelin III';
$music[0]['SONGS'][0] = "Friends";
$music[0]['SONGS'][1] = "Gallows Pole";
$music[0]['SONGS'][2] = "That's the Way";

$music[1]['ID'] = '1';
$music[1]['GROUP'] = 'Led Zeppelin';
$music[1]['ALBUM'] = 'Houses of the Holy';
$music[1]['SONGS'][0] = "Over the Hills and Far Away";
$music[1]['SONGS'][1] = "D'yer Mak'er";
$music[1]['SONGS'][2] = "The Ocean";

$music[2]['ID'] = '2';
$music[2]['GROUP'] = 'Cream';
$music[2]['ALBUM'] = 'Disraeli Gears';
$music[2]['SONGS'][0] = "Strange Brew";
$music[2]['SONGS'][1] = "SWLABR";

echo "<pre>";
print_r($music);
echo "</pre>";


?>

Of course, you could break up your original list into lots of separate arrays, but they would no longer have any direct relationship with one another.

The arrays above can be written differently. For example, I explicitly indicate an index number to your example (e.g. $music[1]). I can leave out the index number and let PHP number them for me automatically (e.g. $music = array(…) ).

Welcome @ITSE1306 to Sitepoint.
Your explanation was outstanding and very clearly presented.
What is more impressive is that this was your first post. Your willingness to participate - actively - and be so very helpful is laudable.

I hope we see you around here quite often; offering your experience and advice.

Yes very impressive post. I too hope would like to see you more often! Welcome!

Thanks! I was once where DoubleDee was/is. And it is a really good question. One I’ve had before in my early days, but could never articulate.

ITSE1306,

Thanks for the response. (I agree with the others you got off to a great start for your first-ever Post!! Welcome!!0 :slight_smile:

Your example was easy to follow and will be a good reference, however I would still like to know what people think about the way I did things in Post #4


array(
	Led Zeppelin=>array(
				Led Zeppelin III=>array(
							Friends=>3:55
							Gallows Pole=>4:58
							That's the Way=>5:38)));
array(
	Led Zeppelin=>array(
				Houses of the Holy=>array(
							Over the Hills and Far Away=>4:50
							D'yer Mak'er=>4:23
							The Ocean=>4:31)))

array(
	Cream=>array(
				Disraeli Gears=>(
							Strange Brew=>2:46
							SWLABR=>2:32)))

I follow the way you did things, but to be honest feel like my example above more accurately reflects how things exist in the real world…

Thinking in Database terms…

  • The are many GROUPS
  • One GROUP can have zero or more ALBUMS
  • One ALBUM has one or more SONGS
  • Each SONG has attributes describing it (e.g. “Length”)

My Nested Array above shows the One to Many to Many relationship - that exists in real life - between GROUPS and ALBUMS and SONGS, whereas your example shows things denormalized and treats a GROUP and an ALBUM at the same level.

This isn’t necessarily wrong, but I think the way I did my array would be closer to 3rd Normal Form in a Database, right?

Of course, your way might be easier to work with in PHP?!

BTW, the whole purpose of this thread was just to better understand how to create Multi-Dimensional Arrays and what they look like in practice, so that I could create some and use them to test a recursive PHP Function that I was working on which is supposed to process any level of Multi-Dimensional Arrays…

Thanks,

Debbie

I think you answered your own question.
In database terms you would set up multiple arrays that are “relational” to each other.
Is there another question on your mind? That you have not quite articulated?

Yeah. Why no one is seeing things as I mentioned above?! :lol:

No one has “articulated” things from a Normalized Database standpoint, and I am curious why.

Wouldn’t my approach also work?

Debbie

The answer to one would probably answer the other. The why is because you’re essentially trying to use an array to duplicate functionality that’s already available through database means. Just from a purely maintenance standpoint, a database is easier to maintain the data than trying to maintain the arrays. Since database recordset access is essentially glorified array access, I don’t see a benefit to trying to accomplish the same thing but have to go through the hassle of loading the array elements yourself.

But that’s just me - use the right tool for the job.

Hi Debbie,

I agree with Dave. I do understand that you are trying to wrap your head around Arrays and you mentioned you have a function that can parse an non or multi-dimensional arrays, But at the end of the day this data should be stored in a database with proper relational integrity, which will make it easier and more efficient than parsing it in PHP.

Steve

I’m just trying to better understand how arrays work and how to build multi-dimensional ones.

The examples I gave were purely academic. I have no need - or honestly desire - to work with multi-dimensional arrays at this point.

I just figured building one with some data that I can easily relate to would be a good exercise.

Since I have figured out my recursive function independent of this conversation, maybe this topic no longer matter?

Thanks,

Debbie

This is wrong. You have two different keys (0 and 1) assigned to a unique value (Led Zeppelin). For it to be true, you should have a combined unique value, like for composed unique indexes:


KEY		VALUE
0		(Led Zeppelin, Led Zeppelin III)
1		(Led Zeppelin, Houses of the Holy)
2		(Cream, Disraeli Gears)

<hr>

Well, to answer in database terms:


$group = [
    '1' => 'Led Zeppelin',
    '2' => 'Cream'
];

$album = [
    '1' => [
        '1' => 'Led Zeppelin',
        '2' => 'Led Zeppelin III'
    ],
    
    '2' => [
        '1' => 'Disraeli Gears'
    ]
];

$song = [
    '1' => [
        '1' => [
            '1' => 'Friends',
            '2' => 'Gallows Pole',
            '3' => 'That's the Way'
        ],
        '2' => [
            '1' => 'Over the Hills and Far Away',
            '2' => 'D\\'yer Mak\\'er',
            '3' => 'The Ocean'
        ]
    ],
    
    '2' => [
        '1' => [
            '1' => 'Strange Brew',
            '2' => 'SWLABR'
        ]
    ]
]

<hr>

You have three tables:

  • one for group: ( group id, group name ),
  • one for album: ( foreign group id key, album id, album name )
  • one for song: ( foreign group id key, foreign album id key, song id, song name )

What is different in databases from associative arrays is that you’d have unique id’s for album and song too:


$group = [
    '[B]1[/B]' => 'Led Zeppelin',
    '[B]2[/B]' => 'Cream'
];

$album = [
    '1' => [
        '[B]1[/B]' => 'Led Zeppelin',
        '[B]2[/B]' => 'Led Zeppelin III'
    ],
    
    '2' => [
        '[B]3[/B]' => 'Disraeli Gears'
    ]
];

$song = [
    '1' => [
        '1' => [
            '[B]1[/B]' => 'Friends',
            '[B]2[/B]' => 'Gallows Pole',
            '[B]3[/B]' => 'That's the Way'
        ],
        '2' => [
            '[B]4[/B]' => 'Over the Hills and Far Away',
            '[B]5[/B]' => 'D\\'yer Mak\\'er',
            '[B]6[/B]' => 'The Ocean'
        ]
    ],
    
    '2' => [
        '3' => [
            '[B]7[/B]' => 'Strange Brew',
            '[B]8[/B]' => 'SWLABR'
        ]
    ]
]


$group = [
    '1' => 'Led Zeppelin',
    '2' => 'Cream'
];

$album = [
    '1' => [
        '1' => 'Led Zeppelin',
        '2' => 'Led Zeppelin III'
    ],
    
    '2' => [
        '1' => 'Disraeli Gears'
    ]
];

$song = [
    '1' => [
        '1' => [
            '1' => [
                        'title'  => 'Friends',
                        'length' => '3:55'
                   ],
            
            '2' => [
                        'title'  => 'Gallows Pole',
                        'length' => '4:58'
                   ],
            
            '3' => [
                        'title'  => 'That\\'s the Way',
                        'length' => '5:38'
                   ]
        ],
            
        '2' => [
            '1' => [
                        'title'  => 'Over the Hills and Far Away',
                        'length' => '4:50'
                   ],
            
            '2' => [
                        'title'  => 'D\\'yer Mak\\'er',
                        'length' => '4:23'
                   ],
            
            '3' => [
                        'title'  => 'The Ocean',
                        'length' => '4:31'
                   ]
        ]
    ],
    
    '2' => [
        '1' => [
            '1' => [
                        'title'  => 'Strange Brew',
                        'length' => '2:46'
                   ],
            
            '2' => [
                        'title'  => 'SWLABR',
                        'length' => '2:32'
                   ]
        ]
    ]
];

Finally, what you’re doing in #Post 4, while it’s not a database approach, it’s not without merit.

You could do something like this:


$bands = [

    'Led Zeppelin' => [
    
        'name'   => 'Led Zeppelin',
        
        'albums' => [
            
            'Led Zeppelin' => [
        
                'title'        => 'Led Zeppelin',
                
                'release year' => '1969',
                
                'songs'        => [
                
                    'Friends' => [
                        'title'  => 'Friends',
                        'length' => '3:55'
                    ],
                    
                    'Gallows Pole' => [
                        'title'  => 'Gallows Pole',
                        'length' => '4:58'
                    ],
                    
                    'That\\'s the Way' => [
                        'title'  => 'That\\'s the Way',
                        'length' => '5:38'
                    ]
                ]
            ],
            
            'Led Zeppelin III' => [
        
                'title'        => 'Led Zeppelin III',
                
                'release year' => '1970',
                
                'songs'        => [
                
                    'Over the Hills and Far Away' => [
                        'title'  => 'Over the Hills and Far Away',
                        'length' => '4:50'
                    ],
                    
                    'D\\'yer Mak\\'er' => [
                        'title'  => 'D\\'yer Mak\\'er',
                        'length' => '4:23'
                    ],
                    
                    'The Ocean' => [
                        'title'  => 'The Ocean',
                        'length' => '4:31'
                    ]
                ]
            ]
        ]
    ],
    
    'Cream' => [
    
        'name'   => 'Cream',
        
        'albums' => [
            
            'Disraeli Gears' => [
        
                'title'        => 'Disraeli Gears',
                
                'release year' => '1967',
                
                'songs'        => [
                
                    'Strange Brew' => [
                        'title'  => 'Strange Brew',
                        'length' => '2:46'
                    ],
                    
                    'SWLABR' => [
                        'title'  => 'SWLABR',
                        'length' => '2:32'
                    ]
                ]
            ]
        ]
    ]
];

and have something very handy for looking up values, like this:


$band_name = 'Led Zeppelin';
$album_title = 'Led Zeppelin III',

$the_songs = $bands[$band_name]['albums'][$album_title];

Using the duplicate values for (key, band name), (key, album title) or (key, song title) instead of using dumb keys like ‘1’, ‘2’ etcetera, saves you the search for the keys of the values.

I guess this is what you were looking for: a little recognition for your idea and a little help to make it work. :slight_smile: It’s not a new idea, but it’s good you’ve thought about it, because databases and arrays don’t necessarily translate one to another. Classic relational databases have stricter rules, but with arrays we can be more flexible.

PS BTW, band entries in $bands are on their way to look like objects. :wink:

Not necessarily true, but, just for fun:

  • a band = 1 object (definitely)
  • a band album = 1 object as a property for the band object (maybe)
  • a song = 1 object as a property for the album object property of the band object (unlikely)

What you’re missing are some methods to help define the behavior of the band.

A little errata:


$band_name = 'Led Zeppelin';
$album_title = 'Led Zeppelin III',

$the_songs = $bands[$band_name]['albums'][$album_title]['songs'];