sort posts by word count in wordpress

I needed to get the word count of each post and display posts according to that order. I need this to identify the posts with the lowest word count and work on them.

So far I have been able to create an array from the word count from each post and sort them all with sort($wc, SORT_NUMERIC). Beyond this I am unable to get posts to display according to this order.

Read More
$args = array('post_type' => 'post', 'posts_per_page' => 20, 'post_status' => 'publish'); 
   $results = get_posts($args);
   $wc = array(); 
   //$p_id = array(); //how do i use this ?       
       foreach($results as $r){
       $wc[] = str_word_count( strip_tags( $r->post_content ));
       //$p_id[] = $->ID; //how do i use this ?
       }
   sort($wc, SORT_NUMERIC);

Just so you know, I am aware of another alternative where you save these values as custom meta fields and then display posts with 'meta_value_num' but I am not allowed to take that route. Any idea how this can be done ? TIA.


This is what I have been trying something like this : But it does not consider post ids. I guess it needs to be like an associative array or something.

 foreach ($wc as $key => $val) {
            echo $key.' => ' .$val . '<br>';
            }

An ideal result would look something like this as I will need to display the associated post title as well.

 1. Post title => 369
 2. Another post title => 548
 3. Yet another title => 895

UPDATE – It works with the solution provided in the accepted answer. If you can come up with better solution, plese write an answer.

Related posts

2 comments

  1. There’s no need to have an array of word counts and an array of post titles mapped by their index. You can create one array indexed by post title with the word counts as the values, then use asort to sort the array by its values while maintaining the index:

    $args = array( 'post_type' => 'post', 'posts_per_page' => 20, 'post_status' => 'publish' );
    $results = get_posts( $args );
    
    $posts = array();
    
    foreach ( $results as $result ) {
        $posts[ $result->post_title ] = str_word_count( strip_tags( $result->post_content ) );
    }
    
    asort( $posts, SORT_NUMERIC );
    
    die( print_r( $posts ) );
    

    If you wanted to sort the array in reverse order you would just use arsort instead of asort

  2. I think $wc should be a multidimensional array with “title” and “number of words”, and then you could use array_mulisort.
    Try somethink like this :

    foreach($results as $r){
      $wc[] = array('title' => $r->post_title, 'nb_words' => str_word_count( strip_tags( $r->post_content )));
    }
    foreach($wc as $key => $post) {
      $nb_words[$key] = $post['nb_words'];
      $title[$key] = $post['title'];
    }
    array_multisort($nb_words, SORT_ASC, $title, SORT_ASC, $wc);
    

    UPDATE – Here is a shorter and better way to use array_multisort:

    $args = array('post_type' => 'post', 'posts_per_page' => 20, 'post_status' => 'publish'); 
    $results = get_posts($args);
    $nb_words = array();
    $title = array();
    foreach($results as $r){
      $nb_words[] = str_word_count( strip_tags( $r->post_content ));
      $title[] = $r->post_title;
    }
    array_multisort($nb_words, SORT_ASC, SORT_NUMERIC, $title);
    for ($i = 0; $i < sizeof($title); $i++) {
      echo $title[$i] . ' => ' . $nb_words[$i] . '<br>';
    }
    

Comments are closed.