Welcome Guest, Not a member yet? Register   Sign In
Multi-Dimensional Array Help
#1

[eluser]jcargilo[/eluser]
Hi there, new to CI/PHP and could use some help building a multi-dimensional array from db queries. In a nutshell, I'm looking to obtain a list of categories into an array, and then within that category array I would like to obtain category info AND an array of assigned items. The format I'm trying to achieve is this:

Code:
Array
(
    [0] => Array
    (
        [id] => 1
        [title] => Category 1
        [rank] => 1
        [item] => Array
        (
              [id] => 1
              [title] => Item 1
              [rank] => 1
        )
    )
    ...
)

Now, I am stumped as to how to embed the second Array into the first. I have two methods in my Model to obtain this information: get_categories and get_items_by_category_id. I tried doing something like the following from my controller to no avail:

Code:
$data['categories'] = $this->categories_model->get_categories();
foreach ($data['categories'] as $category) {
    $category['items'] = $this->items_model->get_items_by_category_id($category['id']);
}

I don't believe the $category variable is being passed by reference, so that's one issue. However, even replacing that with the original array doesn't have any affect. I know I'm going about this wrong, so I'd greatly appreciate some assistance.
#2

[eluser]jwindhorst[/eluser]
You're out of scope. Try something like this:
Code:
$cat_items = array();
$data['categories'] = $this->categories_model->get_categories();
foreach ($data['categories'] as $category) {
    $cat_items[$category]['items'] = $this->items_model->get_items_by_category_id($category['id']);
}

Notice I'm using a new Array, not the one I'm looping through. Also, I'm using the current category in the loop to differentiate the categories with the associated items in the final cat_items array.
#3

[eluser]jwindhorst[/eluser]
Oh, I should add that explanation assumes that $this->items_model->get_items_by_category_id() returns an array.
#4

[eluser]aquary[/eluser]
You have to put & to use variable by reference.

Code:
$data['categories'] = $this->categories_model->get_categories();
foreach ($data['categories'] as &$category) {
    $category['items'] = $this->items_model->get_items_by_category_id($category['id']);
}
#5

[eluser]jwindhorst[/eluser]
Thanks aquary, I was spacing the word for it.

Your fix would work just fine, but I might argue that mine is more readable (especially for someone admitting they are new to PHP). Of course, without seeing what get_items_by_category_id() returns, either solution could have problems.
#6

[eluser]jcargilo[/eluser]
@jwindhorst -

In the following line, if I understand the logic correctly you are essentially adding both the original array AND the items array to the newly created $cat_items array? If that's the case, is it necessary to recreate the original array or was this just for the sake of readability?

Quote:$cat_items[$category]['items'] = $this->items_model->get_items_by_category_id($category['id']);

@aquary -

Thanks for the & pass by reference clue in. That's the piece I was missing to make it work how I had it setup.

------

I chose aquary's method for now since that was what I was actually after. Both methods work fine, I usually try to go with the "less is more" approach and append to an existing array rather than create a new array to move a copy of an existing array and then a child array. Neither approach is wrong that I can see, and your response may actually enlighten me as to why that approach might be better. I'm open to any expert advice you're freely giving out, naturally Smile.

P.S. Yes, both methods are returning a result_array.
#7

[eluser]jwindhorst[/eluser]
@jcargilo it's not necessary to recreate the original array, but for the sake of the next developer that might have to look at the code in the future, I think it's more readable my way. If you had a two categories, let's say fruits and nuts you might have something like this:
Code:
array(
    'fruits'  =>  'items' => array('apple', 'orange', 'pear'),
    'nuts'    =>  'items' => array('pistachio', 'peanuts', 'macedamia')
)

With the pass by reference way, you are going to end up creating two new and distinct arrays. Leaving you with something like I believe:
Code:
$fruits = array( 'items' => array('apple', 'orange', 'pear'));
$nuts   = array( 'items' => array('pistachio', 'peanuts', 'macedamia'));

At that point it really is personal preference. I don't think there is even an optimization question between the two methods although I could be wrong. The reason I say that my way is more readable is simply when you do it by reference you don't see the names of the two arrays you will be left with because they are being generated in a loop.
#8

[eluser]jcargilo[/eluser]
@jwindhorst -

Thanks for taking the time to reply. I'm always objective to learning new "best method" techniques so I have given your suggestion some thought. First off, I tried to write it like you suggested and received an illegal offset type error. Other than that minor inconvenience, I get what you're saying about the readability. Rather than deciphering the PBR variable, your method creates a new array (because the $data['categories'] array is already set) to store both the category details and subset of items. I definitely think, in this case, it's a personal preference and find that it doesn't read any better or worse than the PBR method. Perhaps it's my background in C#, but I simply prefer that method.

However, I'll continue to mull it over (and get it working) and it might just make more sense to do. Thanks again Smile.
#9

[eluser]jwindhorst[/eluser]
@jcargilo

I too think it's a personal preference. I don't think there is anything "wrong" with either method. using my method you at least see what the name of the parent array is. I think I used cat_items above. Regardless you can see that without knowing what is inside the array you're looping over. Therefore you can easily do:
Code:
echo '<pre>';
print_r($cat_items);
echo '</pre>';
then you would see what is stored in your categories and what items are associated with each. With the PBR you won't know what those base level array's are called since they generated on the fly in the loop.

Works is works at the end of the day though!




Theme © iAndrew 2016 - Forum software by © MyBB