【问题标题】:How do I sort by nested php array如何按嵌套的php数组排序
【发布时间】:2011-12-07 07:10:00
【问题描述】:

这是the xml feed I'm accessing的摘录:

这是我当前的代码:

$file = file_get_contents('feed.xml');
$file = preg_replace('/(<role[^>]+>)([^<]+)/si', '$1', $file);
$xml = new SimpleXMLElement($file);

$search_term = preg_replace('/[,.\/\\\(\)\[\]\{\}`~!@#\$%\^&*;:\'"\-_<>]*/is', '', $_GET['work']);

$productions = $xml->xpath('//production');
?>

<table width="300px" cellspacing="5px" cellpadding="5px" border="1px" >
<tr>
<th>year</th>
<th>company</th>
</tr>

<?php
foreach($productions as $prod) {

    $prod_attrs = $prod->attributes();
    $prod_date = $prod_attrs->startdate;

    echo "<tr><td>", $prod_date, "</td><td>", html_encode($prod_attrs->company), "</td></tr>";


    }               
?>

</table>

这是输出:

我的问题是,如何让表格按数字降序排序(即最近一年优先)?我在这里搜索并试图理解sort() 函数(例如this answer),但它仍然有点超出我的能力,我无法弄清楚如何让它在这里工作。


更新

我在玩@Chris Goddard's answer below..

这是我得到的代码,但它似乎没有成功:

<?php


    function html_encode($var){

    $var = html_entity_decode($var, ENT_QUOTES, 'UTF-8');
    $var = htmlentities($var, ENT_QUOTES, 'UTF-8');
    return $var;
}


$file = file_get_contents('feed.xml');
$file = preg_replace('/(<role[^>]+>)([^<]+)/si', '$1', $file);
$xml = simplexml_load_string($file);
$json = json_encode($xml); 
$array = json_decode($json,TRUE); 


$search_term = preg_replace('/[,.\/\\\(\)\[\]\{\}`~!@#\$%\^&*;:\'"\-_<>]*/is', '', $_GET['work']);


$works = $xml->xpath('//work');

foreach($works as $work) {
$Productions = $work->xpath('./production');

$Sorter = array();

foreach ($Productions as $prod) {

$prod_attrs = $prod->attributes();
    $Sorter[$key] = $prod_attrs->startdate;
array_multisort($Sorter, SORT_DESC, $Productions);
  }
}
echo "<pre>".print_r($works, true)."</pre>";
?>

我做错了什么?

【问题讨论】:

    标签: php sorting html-table


    【解决方案1】:

    我不理解该代码的一半(所有正则表达式是什么?),但要实现所需的排序表,您可以简单地做:

    $profile = simplexml_load_file('http://andrewfinden.com/test/feed.xml');
    $productions = $profile->xpath(
        '/profile/repertoire/composer/work/role/production'
    );
    

    加载 XML 并获取在 XML 中出现的所有作品的列表。要对它们进行排序,您可以使用自定义排序:

    usort($productions, function($a, $b) {
        return $b['startdate'] - $a['startdate'];
    });
    

    这将比较 simplexml 元素的开始日期并按降序对它们进行排序。然后只需要迭代产品即可:

    <table>
        <thead>
            <tr>
                <th>Year</th>
                <th>Company</th>
            </tr>
        </thead>
        <tbody>
        <?php foreach ($productions as $production): ?>
            <tr>
                <td><?php echo htmlspecialchars($production['startdate'])?></td>
                <td><?php echo htmlspecialchars($production['company'])?></td>
            </tr>
        <?php endforeach; ?>
        </tbody>
    </table>
    

    See demo

    另见demo for your additional requests in chat,例如将作品限制为按生产开始日期对作品进行审查和分类的作品。

    【讨论】:

    【解决方案2】:

    array_multisort 可以解决问题

    你把一个数组放在第一个数组中(它有每个元素的键、排序值、方向然后是大数组)

    编辑

    $Productions = json_decode(json_encode((array) simplexml_load_string($file)), 1);
    $Sorter = array();
    
    foreach ($Productions as $Key => $prod)
        $Sorter[$Key] = $prod->attributes->startdate;
    array_multisort($Sorter, SORT_DESC, $Productions);
    
    foreach ($Productions as $prod) { ...
    

    【讨论】:

    • 抱歉,这里是一个真正的初学者.. 你介意为我解释一下吗? (顺便说一句,我不能真正更改 xml 文件。我可以,但它会破坏使用这个特定文件的目的)
    • 创建一个名为 Sorter 的新数组,然后对 XML 数组执行 foreach ($products as $key => $product)(搜索 XML2Array,您应该会得到一些结果)。在 foreach 中,您执行 Sorter[$Key] = 之类的操作,然后执行您希望对其进行排序的值,在本例中为年份。最后,做 array_multisort(Sorter, SORT_DESC, $Products);然后是围绕 $Products 的最后一个 foreach 并且它全部排序。希望对老兄有帮助:)
    • 这里有一些代码: $Productions = json_decode(json_encode((array) simplexml_load_string($file)), 1); $排序器 = 数组(); foreach ($Productions as $Key => $prod) $Sorter[$Key] = $prod->attributes->startdate; array_multisort($Sorter, SORT_DESC, $Productions); foreach ($Productions as $prod) { ...
    • @ChrisGoddard 您应该将该代码编辑到您的答案中,而不是将其作为评论留下。
    • @ChrisGoddard - 我已经编辑了我的问题,更新了我如何尝试(但失败)实施您的建议..有什么想法吗?谢谢。
    【解决方案3】:

    您可以将值放在一个数组中,然后使用 usort 按用户定义的函数进行排序。

    请注意,当元素在数组中设置时,它们会转换为字符串。将它们与 XML 对象进行比较并不是您想要的。

    一点解释:

    首先我将 XML 数据放入一个数组中,只是因为这样更容易处理数据。

    然后,我根据我的自定义函数date_sort 对数组进行排序。查看您看到的 usort 文档:

    比较函数必须返回一个小于、等于或 如果第一个参数被认为是大于零 分别小于、等于或大于秒。

    所以,因为要按日期 desc 排序,如果日期相等,则排序顺序也相等(返回 0),如果日期较晚,则它应该在列表中较早(返回 -1),并且如果日期更大,它应该在列表中的后面(返回 1)

    然后,您只需遍历数组打印即可。

    如果你想使用额外的数据,只需将它放在第一个循环的数组中即可。

    $production_array = array();
    foreach($productions as $prod) {
    
        $prod_attrs = $prod->attributes();
        $prod_date = $prod_attrs->startdate;
        $production_array[] = array(
            'date'=>(string) $prod_date,
            'company'=>(string) $prod_attrs->company,
            'review_en'=>(string) $prod->review['quote'],
            'review_de'=>(string) $prod->review->translation
        );
    }
    usort($production_array, 'date_sort');
    
    foreach($production_array as $production) {
        echo "<tr><td>", $production['date'], "</td><td>", html_encode($production['company']), "</td><td>",$production['review_en'], "</td></tr>";
    }
    
    function date_sort($a, $b) {
        if($a['date'] == $b['date']) return 0;
        return $a['date'] > $b['date'] ? -1 : 1;
    }
    

    【讨论】:

    • 谢谢!这就是诀窍(仍然试图理解你为公平所做的事情)。我可以再走一步吗……?然后我尝试循环并提取 数据(最终我想显示最近的评论列表)但无法完成这项工作..我也尝试将它放入数组,但正如我所提到的,仍然不确定它是如何工作的..任何想法我可以如何使用您已经向我展示的内容并提取其他数据?谢谢。
    • @Findo 我编辑了我的答案,向您展示如何向数组添加评论/翻译。并添加了我所做的一些解释。如果还不清楚,请告诉我。
    • 太棒了!也谢谢你解释。我很感激。
    • Arg... 总是一些东西!我刚刚意识到它只显示第一个 - 一些条目有多个评论。他们需要在一个数组中吗?我一直在玩,似乎无法弄清楚..我也无法弄清楚如何将 添加到数组中。
    • 我建议发布另一个问题,寻求有关使用 XML 和数组的帮助。或者更好的是,搜索已经回答的问题,并将它们应用到您的场景中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2021-01-11
    • 2014-04-20
    • 2021-08-07
    • 1970-01-01
    • 2011-04-11
    相关资源
    最近更新 更多