mac_gabe Posted July 18, 2011 Share Posted July 18, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/ Share on other sites More sharing options...
AyKay47 Posted July 18, 2011 Share Posted July 18, 2011 $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. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1244161 Share on other sites More sharing options...
mikesta707 Posted July 18, 2011 Share Posted July 18, 2011 Would it be possible to use a database here? This is the kind of problem databases were made for. Doing this with arrays will take a lot of time, and you could easily make some kind of web interface to add and remove certain species and stuff. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1244180 Share on other sites More sharing options...
Psycho Posted July 18, 2011 Share Posted July 18, 2011 $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 ) ) ) ) Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1244185 Share on other sites More sharing options...
mac_gabe Posted July 18, 2011 Author Share Posted July 18, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1244224 Share on other sites More sharing options...
Psycho Posted July 18, 2011 Share Posted July 18, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1244261 Share on other sites More sharing options...
mac_gabe Posted July 26, 2011 Author Share Posted July 26, 2011 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. Quote Link to comment https://forums.phpfreaks.com/topic/242257-make-multi-array-help/#findComment-1247192 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.