Getting a record set from associative array

Hello

I am dealing with a problem and having a hard time solving it. So need your help!

Imagine I have a comment section in my website, where there are two types of role “member” and “staff”. Both roles can post comment. I want to get the datetime of the first post made by the opposite role. For example, in the following array the latest post was made by “aaa” at 1433566756. So, how do I programitically get the first post made by the opp role (i.e. post made by ccc at 1433566752)

Note: The following array is in reverse chronological order. Meaning, the latest post appears on top. Also, to make it less confusing, I have used unique datetime for each record below.

Array
(
    [0] => Array
        (
            [role] => member
            [username] => aaa
            [datetime] => 1433566756
        )

    [1] => Array
        (
            [role] => member
            [username] => aaa
            [datetime] => 1433566755
        )

    [2] => Array
        (
            [role] => staff
            [username] => ccc
            [datetime] => 1433566754
        )

    [3] => Array
        (
            [role] => staff
            [username] => ccc
            [datetime] => 1433566753
        )

    [4] => Array
        (
            [role] => staff
            [username] => ccc
            [datetime] => 1433566752
        )

    [5] => Array
        (
            [role] => member
            [username] => aaa
            [datetime] => 1433566751
        )

)

please help…

thanks in advance

What exactly is the determination of “opposite”? That isn’t clear to me. Is it just the role or does the decision have to deal with the time too? If it is just the role, I can’t see how you can make the determination. If it is with time, I still don’t see what the determining or deciding factor is with it. Is it the closest time? Is it the time furthest away? etc.

Scott

“opposite” role means if the last comment was made by “staff” then, i need to lookup for the datetime of the “FIRST” comment made by the “member”, or if the last comment was made by the “member” then I need to lookup for the datetime of the “First” comment made by the “staff”.

See the example i mentioned above and u will understand :smile:

When you enter the decision making process, is the datetime of the first comment known? Or do you need to find that out, like from the result set like in your example? I would imagine, the results (the data) are coming from a database? Have you sorted them to begin with for the result? What code do you have currently? Please post the applicable parts.

Scott

the datetime is what i need to figure out from the array based on the above logic. Yes the data is coming from a database but its not possible to post the code because the actual scenario is way more complex hence I have simplified it to explain it in a better way.

And is the result set a query you made, because you need the data before hand for the same response? You didn’t answer, if the result set from the database is already sorted by date before hand or not.

Do both the latest comment and last comment of the two roles need to be found in for a single request? Or are they for different responses?

Sorry for the questions, but understanding the complete problem is necessary for coming up with right the solution.

Scott

Its sorted by primary key in desc order. And in case if you want to know, there is no way i can change the sql query. The only way to get the desired datetime is to loop through the array.

Single request

One last question, will the results always have only the two roles in them?

Scott

Yes

<?php
//Note: $data is your array 

//Resort by array key
function aarsort (&$array, $key){
    $sorter = array();
    $ret = array();
    reset($array);
    foreach($array as $ii => $va){
        $sorter[$ii] = $va[$key];
    }
    asort($sorter);
    foreach ($sorter as $ii => $va){
        $ret[$ii] = $array[$ii];
    }
    $array = $ret;
}

function otherposts($array, $user){
    $otherposts = array();
    foreach($array as $record){
        if($record['role'] !== $user){
            $otherposts[] =    $record;
        }    
    }
    return $otherposts;
}

//Resort by datetime
aarsort($data, 'datetime');

//Viewing person defined as role
$role = 'member';

//Get posts by other person
$otherposts = otherposts($data, $role);

//Array keys
$keys = array_keys($otherposts);

//First key
$first_key = min($keys);
//Last key
$last_key = max($keys);

//These keys can be used to view first or last record or you can use foreach to view all in $otherposts
echo "<pre>";
print_r($otherposts[$first_key]);
print_r($otherposts[$last_key]);
echo "</pre>";

?>

I’ve taken a bit of different route.

function compare_role_time($a, $b) {
    // check to see if the role is the same
    $retval = strnatcmp($a['role'], $b['role']);
    // if it is, then check the time
    if( !$retval ) {
        $retval = ( $a['datetime'] < $b['datetime'] ? 1 : -1 );
    }
    return $retval;
}

// sorts the data by role, then by datetime
function sort_data($data_to_sort) {
     // theoretically, the compare_role_time function could simply be a closure here
     uasort($data_to_sort, 'compare_username_time');
     return $data;
}

$sortedData = sort_data($data);
$latestComment = $sortedData[0];
$lastComment = end($sortedData);

Basically, it sorts the data so that you always have the roles sorted first, then the datetime is sorted in a descending order, which means, if there are only two roles in the data (which you stipulated would be true), then, out of the sort, the latest comment is always first and the last comment of the opposite user is always last.

It doesn’t take into account the exact role though. It assumes you have one/ the latest post in the data and gets you the last comment of the other (opposite) user simply through sorting the datetime in descending order.

Scott

Just to toss array_multisort into the mix …
* original datetimes are not in sequential order

<?php
$test_arr = [0 => [
				'role' => "member"
				, 'username' => "aaa"
				, 'datetime' => "1433566751"
			]
			, 1 => [
				'role' => "member"
				, 'username' => "aaa"
				, 'datetime' => "1433566754"
			]
			, 2 => [
				'role' => "staff"
				, 'username' => "ccc"
				, 'datetime' => "1433566752"
			]
			, 3 => [
				'role' => "staff"
				, 'username' => "ccc"
				, 'datetime' => "1433566753"
			]
			, 4 => [
				'role' => "staff"
				, 'username' => "ccc"
				, 'datetime' => "1433566756"
			]
			, 5 => [
				'role' => "member"
				, 'username' => "aaa"
				, 'datetime' => "1433566755"
			]
			];

$datetimes = [];
foreach ($test_arr as $key => $val) {
	$datetimes[$key] = $val['datetime'];
}

array_multisort($datetimes, SORT_DESC, $test_arr);

echo '<pre>';
var_dump($test_arr);
echo '</pre>';

function find_reply_and_previous_post($array) {
	$temp_key = "";
	$temp_role = "";
	$paired_arr = [];
	foreach ($array as $key => $val) {
		if($temp_role === "") {
			$temp_key = $key;
			$temp_role = $val['role'];
		}
		if($val['role'] !== $temp_role) {
			$paired_arr[0] = $array[$temp_key];
			$paired_arr[1] = $array[$key];
			return $paired_arr;
		}
	}
	return $paired_arr;
}

$paired_posts = find_reply_and_previous_post($test_arr);

echo '<pre>';
var_dump($paired_posts);
echo '</pre>';
?>

Hi Guys

Taking ideas from your logic, i made a simpler version that apparently works

	$datetimeList   = [];
	$latestPostRole = null; // Role of the person who made the last post


             foreach ($Comments as $Posts) {
		$currentRole = $Posts['role'];

		if (!$latestPostRole) {
			$latestPostRole = $Posts['role'];
		}

		// If the role of the latest post does not match the role of the current post, we will add the datetime to the array list.
		if ($latestPostRole != $currentRole) {
			$datetimeList[] = $Post['datetime'];
		} else if (is_array($datetimeList) && count($datetimeList) && $latestPostRole == $currentRole) {

		// Seems we have reached the post that belongs to the person who made the latest post, hence we break the loop
			break;
		}
	}

	$createdAt            = end($datetimeList) ? end($datetimeList) : 0;

What do you guys think? Is it easy and simple?

Thanks for your replies :slight_smile:

What is sorting the comments beforehand? What order are they in? How are you determining you are getting the first comment of the opposite user/ role or the last comment of the determining user role? To me, it looks like you are getting the last/latest post from the determining user/ role and also from the opposite user and that goes against your specification, which states you want the first post from the opposite user.

Scott

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.