0

I have an array:

$initialarray = array(
  0 = array(
    'unit' => 1,
    'class' => 1,
    'value' => 'string1'
  ),
  1 = array(
    'unit' => 1,
    'class' => 2,
    'value' => 'string2'
  ),
  2 = array(
    'unit' => 1,
    'class' => 2,
    'value' => 'string3'
  ),
  3 = array(
    'unit' => 2,
    'class' => 1,
    'value' => 'string4'
  )
  4 = array(
    'unit' => 2,
    'class' => 2,
    'value' => 'string5'
  )
);

What would be the best way to structure it (to group the resulting sub-arrays) depending first on the 'unit' field's values, and then depending on the 'class' field's values, like so:

$resultarray = array(
  // array of all the sub-arrays of 'unit' = 1
  $unit[1] = array(
    // array of all the sub-arrays of 'unit' = 1 and 'class' = 1
    $class[1] = array(
      0 = array(
        'unit' => 1,
        'class' => 1,
        'value' => 'string1'
      )
    )
    // array of all the sub-arrays of 'unit' = 1 and 'class' = 2
    $class[2] = array(
      0 = array(
        'unit' => 1,
        'class' => 2,
        'value' => 'string2'
      ),
      1 = array(
        'unit' => 1,
        'class' => 2,
        'value' => 'string3'
      )
    )
  )
  // array of all the sub-arrays of 'unit' = 2
  $unit[2] = array(
    // array of all the sub-arrays of 'unit' = 2 and 'class' = 1
    $class[1] = array(
      0 = array(
        'unit' => 2,
        'class' => 1,
        'value' => 'string4'
      )
    )
    // array of all the sub-arrays of 'unit' = 2 and 'class' = 2
    $class[2] = array(
      0 = array(
        'unit' => 2,
        'class' => 2,
        'value' => 'string5'
      )
    )
  )
)

I have asked a similar question here and got a working answer for only one iteration, i.e. for only structuring the array by one of the fields. But I could not make the same solution work for multiple iterations, i.e. for more than one field.

Also, is there a solution to structure a multidimensional array depending on more than two fields?

Community
  • 1
  • 1
Томица Кораћ
  • 2,542
  • 7
  • 35
  • 57

3 Answers3

1

I think it's not a way of asking the question. It is very simple , you can do this by playing with arrays,keys and etc.... So first you should try hard for the problem. After If you have any problem in the middle of your tries then you can ask that here. I have solved your problem here is the complete code , but next time please do some work and then only post the problem. Never ask for the code.

foreach ($initialarray as $key1=>$val1)
{
    foreach ($val1 as $key2=>$val2)
    {            

        if($key2=='unit')
        {
            $num=$val2;
            if($val2!=$num)
            $testarr['unit'.$val2]=array();
        }
        if($key2=='class')
        {
            $testarr['unit'.$num]['class'.$val2][]=$val1;
        }

    }
}

print_r($testarr);
srbhbarot
  • 1,317
  • 12
  • 16
  • thank you so much, this worked. Maybe I'm not at the right place for asking questions this simple and I will be more cautious in the future. I am a total beginner in PHP. But I did spend 3 days trying to solve this, and only after failing miserably, decided to ask a question on StackOverflow. I've also searched _a lot_ for the answer on the internet, but couldn' find anything close to your solution. – Томица Кораћ Jun 05 '12 at 17:02
1

I must offer a better way for you and future researchers...

You only need one loop, and you merely need to nominate the result array's key values before using [] to "push" new data into the deepest subarray.

*there is absolutely no need for any condition statements or a second loop.

Code: (Demo)

$initialarray = [
  ['unit' => 1, 'class' => 1, 'value' => 'string1'],
  ['unit' => 1, 'class' => 2, 'value' => 'string2'],
  ['unit' => 1, 'class' => 2, 'value' => 'string3'],
  ['unit' => 2, 'class' => 1, 'value' => 'string4'],
  ['unit' => 2, 'class' => 2, 'value' => 'string5']
];

foreach ($initialarray as $row) {
    $result[$row['unit']][$row['class']][] = $row;
}
var_export($result);

Output:

array (
  1 => 
  array (
    1 => 
    array (
      0 => 
      array (
        'unit' => 1,
        'class' => 1,
        'value' => 'string1',
      ),
    ),
    2 => 
    array (
      0 => 
      array (
        'unit' => 1,
        'class' => 2,
        'value' => 'string2',
      ),
      1 => 
      array (
        'unit' => 1,
        'class' => 2,
        'value' => 'string3',
      ),
    ),
  ),
  2 => 
  array (
    1 => 
    array (
      0 => 
      array (
        'unit' => 2,
        'class' => 1,
        'value' => 'string4',
      ),
    ),
    2 => 
    array (
      0 => 
      array (
        'unit' => 2,
        'class' => 2,
        'value' => 'string5',
      ),
    ),
  ),
)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

If I may express myself in the following manner: I only see the front-end of your problem and know nothing about its back-end, e.g. "Where does the data come from?", "How is it collected and stored", etc. so my answer might not be a real help but still I'll give my "tuppence".
If you can store all that data in a relational database (in form of table(s)) it would be much more easier and faster(!) to select the needed data from the database instead of rearranging arrays, which will take some more time in comparison.
Just as an example you might then select (and store it into an array) all items which have unit = '1' and / or all items which have class = '2'. That would make life much more easier IMHO, than having all the data in a multidimensional array and then try to sort it / rearrange it. Especially if you do that based on more than one property.

Havelock
  • 6,913
  • 4
  • 34
  • 42
  • thanks a lot for your advice. I myself have been thinking about this problem. I'm trying to build a custom CMS using Codeigniter. The units and the classes would be inserted in the database by users. For example, a unit can be a blog post, or a page, and a class is a custom taxonomy for that unit - a page title, or a page text, or a blog title or a blog featuring image etc. The problem is there is not a finite number of neither units nor classes, so that's why I can't put every unit or every class in a separate table. – Томица Кораћ Jun 05 '12 at 16:47
  • Oh, well, then I would suggest leaving SQL do all that job - it's much more effective (cheap on time and resources). For that purpose as I see it you'd need one table for the taxonomy with two columns (attributes) `unit` and `class` to represent the relation (hence *relational* database) between units and classes, which then would be represented in two separate table – Havelock Jun 05 '12 at 18:05
  • Now I see what you mean. I'm considering that too, but I just wanted to see which one of these two solutions would work better. I got the solution to my question, but I will A/B test`both DB structures and see which one will turn out more elegant. Thanks a lot for the advice. – Томица Кораћ Jun 05 '12 at 18:41