简体   繁体   English

在Wordpress中对多维数组进行排序

[英]Sort a multi-dimensional array in Wordpress

Bit of a setup here to explain my issue, but in theory, all I need to do is order a multi-dimensional array before it outputs. 这里有一些设置可以解释我的问题,但是从理论上讲,我需要做的就是在输出多维数组之前对其进行排序。 The issue I'm having is that it's not grouping all the As, Bs and Cs etc together. 我遇到的问题是它没有将所有的As,B和C等归为一组。 I think it needs to sort all the names, before it adds the first letter... 我认为在添加第一个字母之前,需要对所有名称进行排序...

<?php query_posts ( array ( 
    'post_type' => 'programme',
    'category_name' => 'archive',
    'order' => 'DESC' ) ); ?>

<div class="container_12">
    <div class="prefix_1 grid_10 suffix_1">
        <?php while ( have_posts() ) : the_post(); ?>

            <?php 

            $groups = array();

            if ( have_rows('artists') ) {

                while ( have_rows('artists') ) {

                    the_row();


                    // vars
                    $first_name = get_sub_field('first_name');
                    $last_name = get_sub_field('last_name');
                    $first_letter = substr($last_name, 0, 1);


                    // add $first_letter holder to groups
                    if( !isset($groups[ $first_letter ]) ) {

                        $groups[ $first_letter ] = array();

                    }


                    // append artist to group
                    $groups[ $first_letter ][] = $first_name . ' ' . $last_name;

                }

            }

            // ouput
            if( !empty($groups) ): ?>

                <?php foreach( $groups as $letter => $artists ) : ?>

                    <h3><?php echo $letter; ?></h3>

                    <?php foreach( $artists as $artist ): ?>
                        <p><?php echo $artist; ?></p>
                    <?php endforeach; ?>

                <?php endforeach; ?>

            <?php endif; ?>

        <?php endwhile; ?>
    </div>
</div>
<div class="clear"></div>

<?php wp_reset_postdata(); ?>

This currently outputs as: 当前输出为:

在此处输入图片说明

And if you see in the image below, where I have just print_r( $groups ) it needs to add all the arrays into one big array, then sort it. 而且,如果您在下图中看到,我只有print_r($ groups),则需要将所有数组添加到一个大数组中,然后对其进行排序。

在此处输入图片说明

So, ultimately, I'd like to end up with something like: 因此,最终,我想得出以下结果:

A
Joe Allan
Frank Aztec

B
Jane Bank

C
Mike Crichton
Mandy Curtz

UPDATE UPDATE

This is what I have no, and need to sort the artists, alphabetically, by their last name. 这是我所没有的,需要按艺术家的姓氏字母顺序对艺术家进行排序。

<?php if( !empty($groups) ) : ?>
    <?php ksort($groups); ?>
    <?php foreach ( $groups as $letter => $artists ) : ?>
        <div>
        <h3><?php echo $letter; ?></h3>
        <?php asort($artists); ?>
        <?php foreach( $artists as $artist ) : ?>
            <p><?php echo $artist; ?></p>
        <?php endforeach; ?>
        </div>
    <?php endforeach; ?>
<?php endif; ?>

This gives me, using B as an example: 这给我,以B为例:

B

Berendes, Eva

Bloor, Simon

Bloor, Tom

Burt, Theo

Barnes, Kristian

Bajo, Elena

I would like to propose a totally different approach to the problem. 我想提出一种完全不同的方法来解决这个问题。 I know it's not the answer to the exact question you post, but I think it's the answer to your problem. 我知道这不是您发布确切问题的答案,但我认为这是您问题的答案。 I believe your problem is getting the array of artists with the capital letter, so, instead of doing all this PHP nightmare, I would like to propose you get all ordered via MySQL from the DDBB (because ordering via PHP is hard, complex (as you are just watching) and resourcing hog...) and only print the results: 我相信您的问题是要用大写字母来排列艺术家,因此,我建议您不要从DDBB中通过MySQL获得所有订单(因为通过PHP进行订购非常困难,复杂(因为您只是在观看)和资源储备猪...),仅打印结果:

<?php
    // Get access to DDBB manager object
    global $wpdb;

    // Launch a query will give back all ordered, in rows with the capital letter
    // and an array in JSON format with the group names
    $query = $wpdb->get_results("
SELECT 
  GROUP_CONCAT('[', CONCAT(first_name, ', ',last_name), ']' SEPARATOR ', ') as name
, LEFT(last_name, 1) capLetter
FROM artists 
GROUP BY capLetter
ORDER BY last_name, first_name;");

    // Printing the results (they came ordered, ;D):
    foreach ($query as $row) {
        echo $row->capLetter;
        $artists = json_decode($row->name);
        foreach ($artists as $artist) {
            echo $artist;
        }
    }    

?>

I use GROUP_CONCAT to build a JSON array in which we store the values from the DDBB, and with group and order from the MySQL engine is pretty easy to achieve what we want. 我使用GROUP_CONCAT来构建一个JSON数组,在其中存储DDBB中的值,并且使用MySQL引擎中的group和order很容易实现我们想要的。 I only tested the query, and I got the way of launching a custom query with WordPress from http://www.makeuseof.com/tag/working-custom-database-tables-wordpress/ 我只测试了查询,然后从http://www.makeuseof.com/tag/working-custom-database-tables-wordpress/获得了使用WordPress启动自定义查询的方法

Put $groups = array(); $groups = array(); above the first while loop, and also: 在第一个while循环之上,并且:

    if( !empty($groups) ): ?>

        <?php foreach( $groups as $letter => $artists ) : ?>

            <h3><?php echo $letter; ?></h3>

            <?php foreach( $artists as $artist ): ?>
                <p><?php echo $artist; ?></p>
            <?php endforeach; ?>

        <?php endforeach; ?>

    <?php endif; ?>

below the <?php endwhile; ?> <?php endwhile; ?> <?php endwhile; ?>

Like how Chococroc proposed , achieving it using a database query would be efficient . 就像Chococroc提出的那样,使用数据库查询来实现它是有效的。

But if you were already running a query for some other purpose which also retrieves the artists , then rather than running another query , you could use PHP based solution . 但是,如果您已经在运行用于其他目的的查询(该查询还可以检索艺术家),则可以运行基于PHP的解决方案,而不是运行其他查询。

Assuming that you can grab all the names , I am considering an input array like this : 假设您可以获取所有名称,我正在考虑这样的输入数组:

$allNames =
    array(
        array( 'Kate' ,'Allen' )
        ,array( 'Simon' ,'Bloor' )
        ,array( 'Tom' ,'Bloor' )
        ,array( 'Theo' ,'Burt' )
        ,array( 'Ross' ,'Chisholm' )
        ,array( 'Eva' ,'Berendes' )
        ,array( 'Kristian' ,'Barnes' )
        ,array( 'Ashley' ,'Holmes' )
        ,array( 'Joe' ,'Allan' )
        ,array( 'Frank' ,'Aztec' )
        ,array( 'Jane' ,'Bank' )
        ,array( 'Kike' ,'Crichton' )
        ,array( 'Mandy' ,'Curtz' )
    );

The actual solution starts here : 实际的解决方案从这里开始:

/*
 *  Put all the names in to $tempArray as lastName:firstName format
 */

$tempArray = array();

foreach( $allNames as $fullName )
{
    list( $firstName ,$lastName ) = $fullName;
    $tempArray[] = $lastName .':' .$firstName; 
}

/*
 *  Use which ever sort suits your requirement and sort the $tempArray
 */

sort( $tempArray );

/*
 *  Now put the names into groups by the first letter of last name
 */

$groups = array( );

foreach( $tempArray as $value )
{
    $firstLetter = substr( $value ,0 ,1 );

    if( ! isset( $groups[$firstLetter] ) ) $groups[$firstLetter] = array( );

    list( $lastName ,$firstName ) = explode( ":" ,$value );

    $groups[$firstLetter][] = $firstName .' ' .$lastName;
}

Result : 结果:

var_dump( $groups );

Gives : 给出:

  'A' => 
      'Joe Allan'
      'Kate Allen'
      'Frank Aztec'
  'B' => 
      'Jane Bank'
      'Kristian Barnes'
      'Eva Berendes'
      'Simon Bloor'
      'Tom Bloor'
      'Theo Burt'
  'C' => 
      'Ross Chisholm'
      'Kike Crichton'
      'Mandy Curtz'
  'H' => 
      'Ashley Holmes'

If I were to include my solution in to the code you've tried , it could turn to as shown below . 如果将我的解决方案包含在您尝试过的代码中,则可能会如下所示。 This is not tested and probably could need modifications : 这未经测试,可能需要修改:

<?php query_posts ( array (
    'post_type' => 'programme',
    'category_name' => 'archive',
    'order' => 'DESC' ) ); ?>

<div class="container_12">
    <div class="prefix_1 grid_10 suffix_1">
        <?php
        /*
         *  Put all the names in to $tempArray as lastName:firstName format
         */
        $tempArray = array();
        ?>

        <?php while( have_posts() ) : the_post(); ?>

            <?php 
            if( have_rows( 'artists' ) )
            {
                while( have_rows('artists') )
                {
                    the_row();
                    $tempArray[] = get_sub_field( 'last_name' ) .':' .get_sub_field( 'first_name' );
                }
            }
            ?>

        <?php endwhile; ?>

        <?php
        /*
         *  Use which ever sort suits your requirement and sort the $tempArray
         */

        sort( $tempArray );

        /*
         *  Now put the names into groups by the first letter of last name
         */

        $groups = array( );

        foreach( $tempArray as $value )
        {
            $firstLetter = substr( $value ,0 ,1 );

            if( ! isset( $groups[$firstLetter] ) ) $groups[$firstLetter] = array( );

            list( $lastName ,$firstName ) = explode( ":" ,$value );

            $groups[$firstLetter][] = $firstName .' ' .$lastName;
        }
        ?>

        <?php if( ! empty($groups) ): ?>

            <?php foreach( $groups as $letter => $artists ) : ?>

                <h3><?php echo $letter; ?></h3>

                <?php foreach( $artists as $artist ): ?>
                    <p><?php echo $artist; ?></p>
                <?php endforeach; ?>

            <?php endforeach; ?>

        <?php endif; ?>
</div>
</div>
<div class="clear"></div>

<?php wp_reset_postdata(); ?>

Since the author got another problem with sorting the array i will add another answer which hopefully does help. 由于作者在对数组进行排序时遇到了另一个问题,因此我将添加另一个答案,希望对您有所帮助。 As stated in my comment you should use ksort to sort the outer array by key. 如我的评论所述,您应该使用ksort按键对外部数组进行排序。 Now sorting the inner arrays by the last name is a little bit trickier. 现在,按姓氏对内部数组进行排序比较麻烦。 There is a useful function called uasort , which lets the user define a function by which the array entries are getting compared. 有一个有用的函数uasort ,它使用户可以定义一个用来比较数组项的函数。 So what you want to do is something like this: 所以您想要做的是这样的:

ksort($groups);
foreach ($groups as &$group) {
    uasort($group, 'sortLastName');
}
unset($group); 

While using sortLastName as a comparison function, which is defined like this: 在将sortLastName用作比较函数时,其定义如下:

function sortLastName($a, $b) {
    $aLast = end(explode(" ", $a));
    $bLast = end(explode(" ", $b));

    return strcasecmp($aLast, $bLast);
};

Here is a working example on Ideone.com http://ideone.com/vU8ukk 这是Ideone.com http://ideone.com/vU8ukk上的工作示例

Hope i could help you. 希望我能帮助你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM