• Resolved CaiusMartius

    (@caiusmartius)


    All right, at my wits end. Been working on this particular issue for sometime and I can break through it so would truly like some help.

    I have an ‘archive’ of post listings that looks for the date of a post and then prints that date, one right after another. What I want it to do is if it’s the first instance of a particular date (in this case I’m only using the year) it should print it, if it’s a separate instance it should be ignored.

    For example the list is built through the_date as such: 1345, 1356, 1356, 1566, 1765, 1765, 1934

    What it prints out is: 1345, 1356, , 1566, 1765, ,1934.

    Here is the page: https://theendlesswhispers.com/category/mythos/.

    If you see the big ‘watermark’ behind the posts that show the date you can see the years are repeated. I want each date to only show up once.

    I’ve been playing around with if statements constantly and I’ve got an idea how to do that I just can’t figure out how to get the duplicate dates dropped.

    Thanks.

Viewing 11 replies - 1 through 11 (of 11 total)
  • Looks like a straightforward programming exercise:

    Collect dates into an array.
    Sort Array (there are functions for this)
    Iterate through array, add unique dates into new array.
    Use new array.

    There may be some snazzy functions to collapse an array into unique elements, but doing it the “long” way will be quicker.

    Thread Starter CaiusMartius

    (@caiusmartius)

    RossMitchell,

    Yes, an array is what I suspected and I’ve been muddling through some attempts but I still haven’t figured out how to get php to recognize/drop the duplicates.

    So basically:

    for each page build an array with all data (posts, category, DATE, etc.)
    If the date (Y, in this case) is a first appearance…DO STUFF
    else…DO OTHER STUFF

    I can seem to figure out how to do the ‘first appearance’ part.

    M

    Something like this:

    // fill array alldates with the years
    sort($alldates);
    $uniquedates = array();
    $prev_y = null;
    foreach ($alldates as $year)
      if($year != $prev_y) {
        $prev_y = $year;
        $uniquedates[] = $year;
      }
    unset($year);  //never want to leave these bound variables dangling
    unset($alldates);  //not needed any more
    //now do your thing with the $uniquedates array
    Thread Starter CaiusMartius

    (@caiusmartius)

    Ross,

    This looks great. I’m going to implement it straight away but I need to ask some questions, if that’s cool. I don’t like to just drop something in, I prefer to understand how it’s working so I can troubleshoot better and not bother everyone else. ??

    so I”m guessing $alldates is my array that I build with all of it’s variables in it, correct?
    that means $uniquedates is the array we’re going to build from all of the variables in $alldates?

    line 4 and then 5-9 are setting prev_y to be initial empty? then for each entry in the array the if statement compares the $year variable with prev_y which in the first instance they obviously aren’t equal != so now prev_y becomes whatever $year was on the comparison?

    Does this sound like I’ve understanding it well enough?

    Yes it does.

    There is an easier way. ??

    array_unique()

    That will remove any duplicate entries in your array for you without any extra code. So, to remove duplicates and sort could be a single-line operation…

    $my_array = sort (array_unique ($my_array));

    Thread Starter CaiusMartius

    (@caiusmartius)

    Hey guys

    Been working on a bazillion things. I appreciate all the responses.

    catacaustic: I actually don’t want the entries in the array removed because I still need all of the other info that’s part of the array, I just want it do something like

    IF Year IS NOT a duplicate print date, title, excerpt
    IF Year IS a duplicate print title, excerpt

    I haven’t been able to figure it out with my beginners knowledge and I don’t really intend on spending more time on it as I really need to get the navigational part of the site functioning first. So far now, I’ll just call the repeated background time stamps a ‘feature.’ ??

    I’ll look at this again once I get the nav part up and working. Horizontal anchors are apparently a pain in the ar$e.

    Thanks again for everyones ideas!

    Michael

    that’s very different then. That’s not removing dulipcates as you’ve said all along… But it can still be done. It will need a different approach though. As am example that I haven’t thought about too much…

    $values = array (1,2,3,4,5,6,7,7,7,8,9);
    $found = array ();
    
    foreach ($values as $val) {
        echo '<p>'.the_title ().'</p>';
    
        if ( ! in_array ($val, $found) ) {
            $found [] = $val;
            echo '<p>'.the_date ().'</p>';
        }
    }

    The values() array is just an example, but you can use an array of whatever you have and check the values in there. The main part is that you would keep a list of the values that you’ve already output so that you can check against it each time.

    Thread Starter CaiusMartius

    (@caiusmartius)

    Apologies, duplicate may have been the wrong choice.

    This looks very promising though. I’ll give that a shot and see what happens. Thank you very much for taking the time to help.

    In this the $values is my array of dates, correct? The the foreachs look at each date ($val) and based on set parameters does ‘something’ or if it is a repeat ‘does something else.’

    Report back in a few. Thanks again.

    M

    Yes, you’ve got that right. I didn’t go into too much detail because I don’t know how your setup is with that array, but you’ll be able to use that to get what you need out of it.

    Thread Starter CaiusMartius

    (@caiusmartius)

    At long last….

    Okay using everyone’s help here’s what I came up with.

    First I realized my original intent using the_date wasn’t going to work as I have BC dates so I needed to create a meta_key to hold the ‘display’ date I wanted for the timeline.

    After that I used this function to populate my array with the meta_key values.

    function get_meta_values( $key = '', $type = 'post', $status = 'publish' ) {
    
        global $wpdb;
    
        if( empty( $key ) )
            return;
    
        $r = $wpdb->get_col( $wpdb->prepare( "
            SELECT pm.meta_value FROM {$wpdb->postmeta} pm
            LEFT JOIN {$wpdb->posts} p ON p.ID = pm.post_id
            WHERE pm.meta_key = '%s'
            AND p.post_status = '%s'
            AND p.post_type = '%s'
        ", $key, $status, $type ) );
    
        return $r;
    }

    Then using a little finesse from both awesome examples by catacaustic and ross I ended up with this on my category page:

    <?php
      $values = get_meta_values ( 'mythos_year' );
            sort($values);
    
      // array to use for results
    	$uniquedates = array();
    
      // loop through posts, populating $years arrays
    foreach ($values as $val) {
    
        if ( ! in_array ($val, $uniquedates) ) {
    		$uniquedates [] = $val;
    		echo "<li><a href='#";
    		echo $val;
    		echo "'>";
    		echo $val;
    		echo "</a></li>";
    		}
    		}
    ?>

    which in turn, led me to the final version here: mythos page.

    Specifically look at the ‘years’ timeline bar along the bottom of the horizontal scroll.

    It’s not 100% functional yet (the page not the code) because I have to go back in and reconfigure the posts to call the meta key value rather than the year, but I know how to do that now thanks to everything I learned doing this.

    Thank you so much, everyone, it’s been extremely helpful.

Viewing 11 replies - 1 through 11 (of 11 total)
  • The topic ‘Dropping duplicates from an array’ is closed to new replies.