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 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上