Jump to content

make multi-array help


mac_gabe

Recommended Posts

I just cannot get my head round this - so would really appreciate some help. It's for making a taxonomy of species, where species are a subset of genuses (genera), which are a subset of families, which are a subset of orders.

 

I have an array of species data which I want to turn into a multi-array. This is my source as viewed with print_r():

Array ( 
[1] => 
[2] => 
[3] => 
[4] => tao 
[5] => solitarius 
[6] => osgoodi 
[7] => major 
[8] => guttatus 
[9] => 
[10] => bonapartei 
[11] => julius 
[12] => nigrocapillus 
[13] => 
[14] => 
[15] => berlepschi 
[16] => cinereus 
[17] => soui 
etc
)

 

As you can see, first there are some empty element values, then full element values each separated by at least one empty value. The real array is much longer than this.

 

I want to group each group of consecutive values into one sub-array, which will be one genus. The empty elements indicate a new genus (if one empty value), or new family & genus (2 consecutive empty values), or new order, family & genus (3 empties).

In the source data, every order is sure to contain at least one family, every family is sure to contain at least one genus, and every genus is sure to contain at least one species.

 

So this is what I'm aiming for:

Array ( 
[1][0][0][0] =>                     //1st order
[1][1][0][0] =>                     //1st order, 1st family
[1][1][1][0] =>                     //1st order, 1st family, 1st genus
[1][1][1][1] => tao               //1st order, 1st family, 1st genus, 1st species 
[1][1][1][2] => solitarius       //1st order, 1st family, 1st genus, 2nd species
[1][1][1][3] => osgoodi         //etc
[1][1][1][4] => major 
[1][1][1][5] => guttatus 
[1][1][2][0] =>                     //1st order, 1st family, 2nd genus
[1][1][2][1] => bonapartei     //1st order, 1st family, 2nd genus, 1st species
[1][1][2][2] => julius 
[1][1][2][3] => nigrocapillus 
[1][2][0][0] =>                     //1st order, 2nd family 
[1][2][1][0] =>                     //1st order, 2nd  family, 1st genus
[1][2][1][1] => berlepschi      //1st order, 2nd  family, 1st genus, 1st species
[1][2][1][2] => cinereus        //etc
[1][2][1][3] => soui 
etc
)

 

Many thanks as ever for any input, pointers, solutions. If I can solve this I should be able adapt it to add in the genera, families and orders.

Link to comment
Share on other sites

$arr = array('order' => array('family' => array('genus' => 'species' => array('tao','solitarius','osgoodi','major','guttatus'))));

 

that will be the basic structure of this, where you will need to fill in the appropriate information.

However in your case I would use a database here.

Link to comment
Share on other sites

$arr = array('order' => array('family' => array('genus' => 'species' => array('tao','solitarius','osgoodi','major','guttatus'))));

 

that will be the basic structure of this, where you will need to fill in the appropriate information.

However in your case I would use a database here.

 

All you did was create an array in the format he already stated he wanted to get his data in. His problem is he has the data in the format he displayed above and he need to convert it into a multidimensional array. While a database would be the best solution for "storing" the data, we do not know where this data is coming from. It could be that this data is being read in from some other source which he has no control over. In that case, converting the data into a usable structure is still needed.

 

@mac_gabe,

 

Here is a function that will convert your array as you requested. Just call the function using the array of single dimension data and it will be converted.

 

function convertData(&$dataArray)
{
    $ouputArray = array();
    $order   = -1;
    $family  = -1;
    $genus   = -1;
    $level   = 1;
    foreach($dataArray as $value)
    {
        if(empty($value))
        {
            switch($level)
            {
                case 1:
                    $genus++;
                    break;
                case 2:
                    $family++;
                    $genus = 0;
                    break;
                case 3:
                    $order++;
                    $family = 0;
                    $genus  = 0;
                    break;
            }
            $level++;
        }
        else
        {
            $ouputArray['order_'.$order]['family_'.$family]['genus_'.$genus][] = $value;
            $level = 1;
        }
    }
    $dataArray = $ouputArray;
}

 

Example usage:

$data = array ( 
'',
'',
'',
'tao',
'solitarius',
'osgoodi',
'major',
'guttatus',
'',
'bonapartei',
'julius',
'nigrocapillus',
'',
'',
'berlepschi',
'cinereus ',
'soui'
);

echo "<pre>Before:\n";
print_r($data);

convertData($data);

echo "\nAfter:\n";
print_r($data);

 

Output:

Before:
Array
(
    [0] => 
    [1] => 
    [2] => 
    [3] => tao
    [4] => solitarius
    [5] => osgoodi
    [6] => major
    [7] => guttatus
    [8] => 
    [9] => bonapartei
    [10] => julius
    [11] => nigrocapillus
    [12] => 
    [13] => 
    [14] => berlepschi
    [15] => cinereus 
    [16] => soui
)

After:
Array
(
    [order_0] => Array
        (
            [family_0] => Array
                (
                    [genus_0] => Array
                        (
                            [0] => tao
                            [1] => solitarius
                            [2] => osgoodi
                            [3] => major
                            [4] => guttatus
                        )

                    [genus_1] => Array
                        (
                            [0] => bonapartei
                            [1] => julius
                            [2] => nigrocapillus
                        )
                )

            [family_1] => Array
                (
                    [genus_0] => Array
                        (
                            [0] => berlepschi
                            [1] => cinereus 
                            [2] => soui
                        )
                )
        )
)

Link to comment
Share on other sites

That is nothing short of phenomenal, mjdamato! Many thanks - I'm still trying to understand it but can already see it works.

 

Thanks also aykay and mikesto for the advice to use a database. I did wonder whether I was trying to go about this the wrong way, but since I've never actually used a database successfully, I thought I'd have a go without if I could.

 

FWIW, the data originally comes from one large excel spreadsheet with all the orders, families, genera and species in a big table. With lots of other information.

 

The relevant part starts with order 1 in row 1 col 1;  family 1 in row 2 col 2; genus 1 in row 3 col 3; species 1 in row 4 col 4; species 2 in row 5 col 4 etc.

 

As mjdamato rightly says, even if I do ultimately store the data in a database, I think I would still probably need to clean it up like this, or in a similar fashion, before I can store it.

Link to comment
Share on other sites

The relevant part starts with order 1 in row 1 col 1;  family 1 in row 2 col 2; genus 1 in row 3 col 3; species 1 in row 4 col 4; species 2 in row 5 col 4 etc.

 

So, you are only processing the 4th column from the Excel spreadsheet. Why not process the entire spreadsheet so you can properly associate the species with "named" Order, Family, & Genus values? If you convert the spreadsheet to a csv file it will be a simple task. You could then take that a step further and use that processed data to create your database.

Link to comment
Share on other sites

Well, I am actually processing the whole lot, but I figured if I could work out how to do col 4, I could use the same method for the other ones.

 

I'm doing OK, I've done the "first column": "orders". On the face of it, that's a very easy column. Now rather than nesting the arrays though I'm numbering them (1.0.0.0., 2.0.0.0. etc). I realise now that you obviously can't have a value for a parent array (ie orders) in the multi-dim-array set up I had originally conceived, because that "parent" value doesn't exist as such in the array structure - it is just the whole content of the array it contains.

 

Then I've also done "col 2" "families" (1.1.0.0., 1.2.0.0., 2.1.0.0. etc) - using your method i.e. look to see if the previous line contained an order, if it does reset the counter to 1, if not keep counting. That worked very nicely.

 

I still have to do col 3 which is "genera" - but I took a break because I needed to do some other stuff, but I should be able to do it - and then redo col 4 in this manner. It requires quite a bit of nesting of clauses, which as a beginner, I find a bit taxing so is slow for me to do, but I am able to do it.

 

After your help, my problem is now not so much how to write the code, but what design the database should take, because I find it hard to look round the corner to see what will be most useful.

 

I figure if every species, genus, family and order has a unique number, and those numbers are logically connected (1.0.0.0., 1.2.3.1 etc ), that should be enough to calculate all relationships and sort orders, but I'm not sure how I should store that number. At the moment, I'm just prepending it to the name, but maybe it would be better to use it in the keys of the arrays. Or create a multi-dim-array with name in one array and numbers in the other.

 

When I have done all that, I intend to use the numbered arrays to make further multi-dimensional arrays, with useful pairs of data. That way I way I can reduce the size of the arrays and load just what I need on a particular part of a web page and no more.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.