doudang8824 2018-02-01 22:14
浏览 108
已采纳

PHP对齐不同长度的多个数组

I'm probably just overlooking the obvious but I'd like to blame it on the fact that I'm new to PHP.

I have some number of arrays being returned with similar information but differing amounts of it.

I'll put some example arrays below:

(t1-s1-1=1, t1-s1-2=1, t1-s2-1=1, t1-s2-2=1)

(t2-s1-1=1, t2-s2-1=2, t2-s2-2=1)

(t3-s1-1=1, t3-s2-1=1, t3-s3-1=1, t3-s3-2=3)

So I would like to make a table out of this information. Something like this:

test ..  s1-1 ..  s1-2 ..  s2-1 ..  s2-2 ..  s3-1 ..  s3-2
t1  ........1 .....1  ..........1 ....... 1.........1..........1
t2  ........1 .......X..........1..........1........1..........1
t3  ........1 .......X..........1..........X........1..........1

( where x is something that wasn't there. )

So every array has an s1 but could have s1-1, s1-2, s1-3 or simply s1-1. That creates very different sized arrays.

The problem is that each array can have wildly different information and because they are Indexed arrays instead of Associative arrays I'm not sure how to best equalize them. I can't consistently say index 3 is s1-3 or something else.

I can't just loop through manually because I never know where a gap will appear. I can't look for specific indexes because the arrays aren't associative so the titles are built into the value and I don't know how to access them separately.

Any good ideas out there that maybe a newbie is overlooking? I'm open to non-tabular display ideas as well as long as I can easily sort and display the information.

Thanks

  • 写回答

2条回答 默认 最新

  • duanjizi9443 2018-02-01 23:42
    关注

    I'm assuming your original arrays contain values as string, so for instance, in PHP syntax, they look like:

    ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
    

    Basically, you should create a bi-dimensional array:

    • go through all arrays and by using a regex extract the different parts, that is, for the first element in the array above: t1 (the index for the first level in the bi-dimensional array), s1-1 (the index for the second level in the bi-dimensional array) and the value 1
    • insert the value in the bi-dimensional array
    • keep in a separate array, let's call it allColumns every second index above (sx-y), even you will have duplicate values you can, at the end, delete those duplicate and order it alphabetically

    After that, you will have all the value in the bi-dimensional array but you still miss the gaps, so what you can do it iterate over the bi-dimensional array, and for every dimension tz (t1, t2,...), go through for all the values stored in allColumns and if you don't find the entry for that sx-y in the bi-dimensional array for that tz, add it with value x (or probably with value = 0)

    I think an example can clarify the above:

    // arrays of arrays, I don't know how you receive the data
    $arrays = [
        ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1'],
        ['t2-s1-1=1', 't2-s2-1=2', 't2-s2-2=1'],
        ['t3-s1-1=1', 't3-s2-1=1', 't3-s3-1=1', 't3-s3-2=3']
    ];
    
    // bi-dimensional array
    $output = [];
    
    // it will store all columns you find in the $arrays entry
    $allColumns = [];
    
    // iterate for every array you receive, i.e. ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
    foreach ($arrays as $array) {
        // iterate over every element in the array: 't1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1' and 't1-s2-2=1'
        foreach ($array as $item) {
            // extract the parts on every element: $matches is an array containing the different parts
            preg_match('/^(t\d+)-(s\d+-\d+)=(\d+)/', $item, $matches);
        /**
         * $matches[0] would contains the element if matched: 't1-s1-1=1'
         * $matches[1] would contains 't1' if matched
         * $matches[2] would contains 's1-1' if matched
         * $matches[2] would contains 1 (integer) if matched
         */
            if (!empty($matches)) {
                $output[$matches[1]][$matches[2]] = $matches[3];
                $allColumns[] = $matches[2];
            }
        }
    }
    
    // clean duplicates
    $allColumns = array_unique($allColumns);
    
    // sort values alphabetically
    sort($allColumns);
    
    // iterate over the just created bi-dimensional array
    foreach ($output as $row => $columns) {
        // iterate for all columns collected before
        foreach ($allColumns as $column) {
            // if one of column in 'allColumns' doesn't exit in $output you added in the correct place adding a zero value
            if (!in_array($column, array_keys($columns))) {
                $output[$row][$column] = 0;
            }
        }
    }
    

    To print the output you should only iterate over $ouput

    This will be the array internally:

    (
     [t1] => Array
        (
            [s1-1] => 1
            [s1-2] => 1
            [s2-1] => 1
            [s2-2] => 1
            [s3-1] => 0
            [s3-2] => 0
        )
    
    [t2] => Array
        (
            [s1-1] => 1
            [s2-1] => 2
            [s2-2] => 1
            [s1-2] => 0
            [s3-1] => 0
            [s3-2] => 0
        )
    
    [t3] => Array
        (
            [s1-1] => 1
            [s2-1] => 1
            [s3-1] => 1
            [s3-2] => 3
            [s1-2] => 0
            [s2-2] => 0
        )
    
    )
    

    It exists other ways to implement the above, like skip the step where you fill the gaps and do it on the fly, ...

    Updated The simplest way to display the results in a HTML page is by embedding a php script to iterate over the associative array and compose the HTML table (I encourage you to study and research MVC to separate logic from the view)

    <!DOCTYPE html>
    <?php
    // arrays of arrays, I don't know how you receive the data
    $arrays = [
        ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1'],
        ['t2-s1-1=1', 't2-s2-1=2', 't2-s2-2=1'],
        ['t3-s1-1=1', 't3-s2-1=1', 't3-s3-1=1', 't3-s3-2=3']
    ];
    
    // bi-dimensional array
    $output = [];
    
    // it will store all columns you find in the $arrays entry
    $allColumns = [];
    
    // iterate for every array you receive, i.e. ['t1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1', 't1-s2-2=1']
    foreach ($arrays as $array) {
        // iterate over every element in the array: 't1-s1-1=1', 't1-s1-2=1', 't1-s2-1=1' and 't1-s2-2=1'
        foreach ($array as $item) {
            // extract the parts on every element: $matches is an array containing the different parts
            preg_match('/^(t\d+)-(s\d+-\d+)=(\d+)/', $item, $matches);
            /**
             * $matches[0] would contains the element if matched: 't1-s1-1=1'
             * $matches[1] would contains 't1' if matched
             * $matches[2] would contains 's1-1' if matched
             * $matches[2] would contains 1 (integer) if matched
             */
            if (!empty($matches)) {
                $output[$matches[1]][$matches[2]] = $matches[3];
                $allColumns[] = $matches[2];
            }
        }
    }
    
    // clean duplicates
    $allColumns = array_unique($allColumns);
    
    // sort values alphabetically
    sort($allColumns);
    
    // iterate over the just created bi-dimensional array
    foreach ($output as $row => $columns) {
        // iterate for all columns collected before
        foreach ($allColumns as $column) {
            // if one of column in 'allColumns' doesn't exit in $output you added in the correct place adding a zero value
            if (!in_array($column, array_keys($columns))) {
                $output[$row][$column] = 0;
            }
        }
    }
    ?>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Table Page</title>
    </head>
    <body>
    
    <table>
        <thead>
        <?php
            echo '<tr><th>Test</th>';
            foreach ($allColumns as $head) {
                echo sprintf('<th>%s</th>', $head);
            }
        echo '</tr>';
        ?>
        </thead>
        <tbody>
        <?php
            foreach ($output as $key => $columns) {
                echo sprintf('<tr><td>%s</td>', $key);
                foreach ($columns as $column) {
                    echo sprintf('<td>%s</td>', $column);
                }
                echo '</tr>';
            }
        ?>
    
        </tbody>
    </table>
    </body>
    </html>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么