This question is sort of carried on from an earlier question of mine here.
However, I would like to illustrate this in the most basic terms, with the hope that someone may be able to help me find a solution to this.
Consider this multidimensional array:
$images = array(
0 = array(
'height' => 100
),
1 = array(
'height' => 90
),
2 = array(
'height' => 60
),
3 = array(
'height' => 30
)
);
Notice that the array is already sorted by height descending!
These images need to be pushed into three columns, whilst trying to keep the height of the columns as even as possible. So the resulting array (of the above example) will look like this:
$gallery_columns = array(
1 => array(
'height' => 100
'images' => array(
0 = array(
'height' => 100
),
)
),
2 => array(
'height' => 90
'images' => array(
0 = array(
'height' => 90
),
)
),
3 => array(
'height' => 90
'images' => array(
0 = array(
'height' => 60
),
1 = array(
'height' => 30
),
)
)
);
I am struggling to write an algorithm to achieve the above. Can anybody see a good way of achieving this without using a lot of nested loops etc?
This could be what you are looking for:
$images = array(
0 => array(
'height' => 100
),
1 => array(
'height' => 90
),
2 => array(
'height' => 60
),
3 => array(
'height' => 30
)
);
$gallery_columns = array(
1 => array(
'height' => 0,
'images' => array()
),
2 => array(
'height' => 0,
'images' => array()
),
3 => array(
'height' => 0,
'images' => array()
)
);
foreach ($images as $img)
{
// start with first column as the shortest
$shortest_colm = &$gallery_columns[1];
// loop over all the columns, updating the shortest column if shorter
for ($i = 2; $i <= 3; $i++)
{
if ($gallery_columns[$i]['height'] < $shortest_colm['height'])
{
$shortest_colm = &$gallery_columns[$i];
}
}
// push the image into the shortest column
$shortest_colm['height'] += $img['height'];
$shortest_colm['images'][] = $img;
}
print_r($gallery_columns);
Outputs:
Array
(
[1] => Array
(
[height] => 100
[images] => Array
(
[0] => Array
(
[height] => 100
)
)
)
[2] => Array
(
[height] => 90
[images] => Array
(
[0] => Array
(
[height] => 90
)
)
)
[3] => Array
(
[height] => 90
[images] => Array
(
[0] => Array
(
[height] => 60
)
[1] => Array
(
[height] => 30
)
)
)
)
Bonus:
foreach($gallery_columns as &$column)
{
shuffle($column['images']);
}
Since you are inserting your images in order from largest to smallest, you could shuffle the images once you are done inserting. That way it won't have all the large images at the top, and the small ones at the bottom.