以平衡的方式将多个项目数组分成两列

时间:2017-11-22 11:34:00

标签: javascript php arrays logic

对于非描述性标题,我不知道如何描述这个。在我的网站上,我有一个FAQ页面,在该页面上是主题组,每个主题都有问题。例如:

FAQ
  - Topic 1
     - Question
     - Question
     - Question
  - Topic 2
     - Question
     - Question
     - Question
  - Topic 3
     - Question
     - Question
     - Question
     - Question

我需要将这些主题分成两个列,以便它们平衡。例如,将上述主题分为两列的最平衡方式是在左栏中有主题1和主题2(60%的问题),然后在右栏中有主题3(40%的问题)。它看起来像这样:

Illustration 1

我无法弄清楚我需要做的事情背后的逻辑。我现在这样做的方法是计算每个块的百分比,然后遍历块并将它们放入第一列,直到增量百分比大于50,然后切换到第二列。最终看起来像这样:

Illustration 2

显然,这不是平衡的。这看似简单的任务实际上是非常复杂的,还是我完全错过了这里的一些东西?我在PHP中对此进行了编码,但我也标记了JavaScript,因为这似乎更像是一个逻辑问题。

2 个答案:

答案 0 :(得分:0)

如果我正确理解逻辑,你想要填满左侧,直到达到或超过50%,然后将其余部分倾倒到右侧。

在这里,我使用recursiveregular形式的count()来计算问题的数量,然后找到中点。

PHP:(Demo

$FAQ=[
    'Topic 1'=>['Question1','Question2','Question3'],
    'Topic 2'=>['Question4','Question5','Question6'],
    'Topic 3'=>['Question7','Question8','Question9','Question10']
];
$mid_point=(count($FAQ,1)-count($FAQ))/2;

$tally=0;
foreach($FAQ as $k=>$a){
    if($tally<=$mid_point){
        $leftside[$k]=$a;
    }else{
        $rightside[$k]=$a;
    }
    $tally+=count($a);
}

var_export($leftside);
echo "\n\n";
var_export($rightside);

输出:

// leftside array:
array (
  'Topic 1' => 
  array (
    0 => 'Question1',
    1 => 'Question2',
    2 => 'Question3',
  ),
  'Topic 2' => 
  array (
    0 => 'Question4',
    1 => 'Question5',
    2 => 'Question6',
  ),
)

// rightside array
array (
  'Topic 3' => 
  array (
    0 => 'Question7',
    1 => 'Question8',
    2 => 'Question9',
    3 => 'Question10',
  ),
)

Here is another demo其中主题1有5个问题,主题2有3个问题,主题3有1个问题。

答案 1 :(得分:0)

很抱歉回答我自己的问题。这是我想出来的。我确定这不是最好的方法,所以如果你有更好的方法,请告诉我。

$sections = array (
    array(
        'section_title' => 'Section 1',
        'items' => array (
            'Item 1',
            'Item 2',
            'Item 3'
        )
    ),
    array(
        'section_title' => 'Section 2',
        'items' => array (
            'Item 1',
            'Item 2',
            'Item 3'
        )
    ),
    array(
        'section_title' => 'Section 3',
        'items' => array (
            'Item 1',
            'Item 2',
            'Item 3',
            'Item 4'
        )
    )
);

$left_col = array();
$right_col = $sections; // Put all items into the right column initially

$left_col_height = 0;
$right_col_height = 0;

foreach ( $right_col as $arr ) {
    $right_col_height += count( $arr[ 'items' ] ); // Get the count of all items in the right column
}

foreach ( $right_col as $key => $val ) {
    // Get height/count of the current block of items
    $block_height = count( $val[ 'items' ] );
    // Get difference between height of right column and left column
    $cur_col_diff = $right_col_height - $left_col_height;
    // Calculate what the heights of the columns would be if the block was moved
    $next_left_col_height = $left_col_height + $block_height;
    $next_right_col_height = $right_col_height - $block_height;
    // Calculate what the difference between the two columns would be if the block was moved
    $next_col_diff = abs( $next_right_col_height - $next_left_col_height );
    if ( $next_col_diff < $cur_col_diff ) {
        // The difference betweens the columns would be less if the block was moved, so move it
        array_push( $left_col, $val );
        unset( $right_col[ $key ] );
        $left_col_height += $block_height;
        $right_col_height -= $block_height;
    }
    else
        break;
}

Here's the working PHP code.