调整列宽数组以适应 Bootstrap 网格系统
Adapt array of column widths to fit Bootstrap grid system
我正在将系统转换为 Bootstrap 网格,我遇到的问题是如何 将 PHP 中数组的当前宽度转换为最接近的/"best fit" 在 Bootstrap?
我的想法是让新的 Bootstrap 列宽基于旧值,遗憾的是旧数据库有一些我需要适应的奇怪值。以下是旧列宽和列数的字符串的六个示例;
%30,%40,%30,%
| 3
%,%,%,%
| 4
180,1070,,
| 2
20,80,,
| 2
75%,25%,20%,
| 2
,,,
| 1
PHP代码:
// example of output from database
$numberOfColumnsFromDatabase = 3;
$stringFromDatabase = '%30,%40,%30,%';
// NOT WORKING as intended:
// 3 cols with string '%30,%40,%30,%'
// Working as intended:
// 2 cols with string '180,1070,,'
// 4 cols with string '%,%,%,%'
// 2 cols with string '75%,25%,20%,'
// 1 cols with string ',,,'
echo 'Original string: "'.$stringFromDatabase.'"'."\n";
// strip percentage and explode to array
$stringStripped = str_replace('%','',$stringFromDatabase);
$columnArrayOld = explode(",", $stringStripped);
// only use the amount of columns from database
$cols = $numberOfColumnsFromDatabase;
$arrayShortened = array_slice($columnArrayOld, 0, $cols);
// sum it up
$fullWidth = array_sum($arrayShortened);
echo 'Full width = '.$fullWidth."\n";
// valid Bootstrap widths
$arrayToSearch = array(8.3, 16.6, 25, 33.3, 41.6, 50, 58.3, 66.6, 75, 83.3, 91.6, 100);
// calculate % of full width
$columnArrayStripped = array();
$columnArrayNew = array();
if($fullWidth > 0){
foreach($arrayShortened as $key => $value){
if(array_key_exists($key, $arrayShortened)) {
if ($columnArrayOld[$key] == '') {
break;
} else {
$percentage = round($arrayShortened[$key]*10)/$fullWidth*10;
$closest = getClosest($percentage,$arrayToSearch);
array_push($columnArrayStripped,$closest);
array_push($columnArrayNew,$closest.'%');
}
}
}
}
else{
//generate new equal width Bootstrap layout based on number of columns
//but only if exploded array does not equal column number
$columnArrayNew = array();
if(count($columnArrayStripped) != $cols) {
// if we cant retrieve widths
for($i=0;$i<$cols;$i++){
$percentage = round(intval(1000/$cols))/10;
array_push($columnArrayStripped, $percentage);
array_push($columnArrayNew, $percentage.'%');
}
}
}
echo 'New clean string: "'.implode(',',$columnArrayStripped).'"'."\n";
echo 'New percentage string: "'.implode(',',$columnArrayNew).'"'."\n";
function getClosest($search, $arr) {
$closest = null;
foreach ($arr as $item) {
if ($closest === null || abs($search - $closest) > abs($item - $search)) {
$closest = $item;
}
}
return $closest;
}
输出:
Original string: "%30,%40,%30,%"
Full width = 100
New clean string: "33.3,41.6,33.3"
New percentage string: "33.3%,41.6%,33.3%"
如您所见,33.3 + 41.6 + 33.3 大于 100%。我明白为什么结果是这样的,因为它的目标是最接近的,但是我怎样才能避免这样的问题呢?我的目标是使生成的字符串具有有效的 bootstrap 宽度,但总数必须在 99.7 和 100.3 之间。
(我也用正则表达式标记,以防答案在那里)
由于缺乏初步反应(没有答案和很少的意见),我最终自己解决了。但我会暂时不标记最佳答案,以防万一有关于如何使用正则表达式解决它的好主意。
这是我的解决方案
phpfiddle demo
更改代码:
if($fullWidth > 0){
foreach($arrayShortened as $key => $value){
if(array_key_exists($key, $arrayShortened)) {
if ($columnArrayOld[$key] == '') {
break;
} else {
$percentage = round($arrayShortened[$key]*10)/$fullWidth*10;
$closest = getClosest($percentage,$arrayToSearch);
array_push($columnArrayStripped,$closest);
array_push($columnArrayNew,$closest.'%');
}
}
}
echo 'Array sum: '.array_sum($columnArrayStripped)."\n";
// if max value in array > 100, reduce max value with 8.3
if(array_sum($columnArrayStripped) > 100){
$maxKey = array_search(max($columnArrayStripped),$columnArrayStripped);
if($maxKey) {
$columnArrayStripped[$maxKey] -= $arrayToSearch[0];
$columnArrayNew[$maxKey] = $columnArrayStripped[$maxKey].'%';
}
}
}
我正在将系统转换为 Bootstrap 网格,我遇到的问题是如何 将 PHP 中数组的当前宽度转换为最接近的/"best fit" 在 Bootstrap?
我的想法是让新的 Bootstrap 列宽基于旧值,遗憾的是旧数据库有一些我需要适应的奇怪值。以下是旧列宽和列数的字符串的六个示例;
%30,%40,%30,%
|3
%,%,%,%
|4
180,1070,,
|2
20,80,,
|2
75%,25%,20%,
|2
,,,
|1
PHP代码:
// example of output from database
$numberOfColumnsFromDatabase = 3;
$stringFromDatabase = '%30,%40,%30,%';
// NOT WORKING as intended:
// 3 cols with string '%30,%40,%30,%'
// Working as intended:
// 2 cols with string '180,1070,,'
// 4 cols with string '%,%,%,%'
// 2 cols with string '75%,25%,20%,'
// 1 cols with string ',,,'
echo 'Original string: "'.$stringFromDatabase.'"'."\n";
// strip percentage and explode to array
$stringStripped = str_replace('%','',$stringFromDatabase);
$columnArrayOld = explode(",", $stringStripped);
// only use the amount of columns from database
$cols = $numberOfColumnsFromDatabase;
$arrayShortened = array_slice($columnArrayOld, 0, $cols);
// sum it up
$fullWidth = array_sum($arrayShortened);
echo 'Full width = '.$fullWidth."\n";
// valid Bootstrap widths
$arrayToSearch = array(8.3, 16.6, 25, 33.3, 41.6, 50, 58.3, 66.6, 75, 83.3, 91.6, 100);
// calculate % of full width
$columnArrayStripped = array();
$columnArrayNew = array();
if($fullWidth > 0){
foreach($arrayShortened as $key => $value){
if(array_key_exists($key, $arrayShortened)) {
if ($columnArrayOld[$key] == '') {
break;
} else {
$percentage = round($arrayShortened[$key]*10)/$fullWidth*10;
$closest = getClosest($percentage,$arrayToSearch);
array_push($columnArrayStripped,$closest);
array_push($columnArrayNew,$closest.'%');
}
}
}
}
else{
//generate new equal width Bootstrap layout based on number of columns
//but only if exploded array does not equal column number
$columnArrayNew = array();
if(count($columnArrayStripped) != $cols) {
// if we cant retrieve widths
for($i=0;$i<$cols;$i++){
$percentage = round(intval(1000/$cols))/10;
array_push($columnArrayStripped, $percentage);
array_push($columnArrayNew, $percentage.'%');
}
}
}
echo 'New clean string: "'.implode(',',$columnArrayStripped).'"'."\n";
echo 'New percentage string: "'.implode(',',$columnArrayNew).'"'."\n";
function getClosest($search, $arr) {
$closest = null;
foreach ($arr as $item) {
if ($closest === null || abs($search - $closest) > abs($item - $search)) {
$closest = $item;
}
}
return $closest;
}
输出:
Original string: "%30,%40,%30,%"
Full width = 100
New clean string: "33.3,41.6,33.3"
New percentage string: "33.3%,41.6%,33.3%"
如您所见,33.3 + 41.6 + 33.3 大于 100%。我明白为什么结果是这样的,因为它的目标是最接近的,但是我怎样才能避免这样的问题呢?我的目标是使生成的字符串具有有效的 bootstrap 宽度,但总数必须在 99.7 和 100.3 之间。
(我也用正则表达式标记,以防答案在那里)
由于缺乏初步反应(没有答案和很少的意见),我最终自己解决了。但我会暂时不标记最佳答案,以防万一有关于如何使用正则表达式解决它的好主意。
这是我的解决方案 phpfiddle demo
更改代码:
if($fullWidth > 0){
foreach($arrayShortened as $key => $value){
if(array_key_exists($key, $arrayShortened)) {
if ($columnArrayOld[$key] == '') {
break;
} else {
$percentage = round($arrayShortened[$key]*10)/$fullWidth*10;
$closest = getClosest($percentage,$arrayToSearch);
array_push($columnArrayStripped,$closest);
array_push($columnArrayNew,$closest.'%');
}
}
}
echo 'Array sum: '.array_sum($columnArrayStripped)."\n";
// if max value in array > 100, reduce max value with 8.3
if(array_sum($columnArrayStripped) > 100){
$maxKey = array_search(max($columnArrayStripped),$columnArrayStripped);
if($maxKey) {
$columnArrayStripped[$maxKey] -= $arrayToSearch[0];
$columnArrayNew[$maxKey] = $columnArrayStripped[$maxKey].'%';
}
}
}