3

I have arrays containing objects that look like the following, first array:

Array
(
[1] => stdClass Object
    (
        [matchID] => 1
        [tm] => 2014-01-16 08:55:13
        [playertm] => 2014-01-16 08:55:14
    )

[2] => stdClass Object
    (
        [matchID] => 2
        [tm] => 2014-01-16 09:53:50
        [playertm] => 2014-01-16 09:53:52
    )

[3] => stdClass Object
    (
        [matchID] => 3
        [tm] => 2014-01-16 09:58:49
        [playertm] => 2014-01-16 09:58:57
    )

[4] => stdClass Object
    (
        [matchID] => 4
        [tm] => 2014-01-17 08:44:34
        [playertm] => 2014-01-17 08:44:35
    )
)

Second array:

Array
(
[3] => stdClass Object
    (
        [matchID] => 3
        [tm] => 2014-01-16 09:58:49
        [playertm] => 2014-01-16 09:58:57
    )

[4] => stdClass Object
    (
        [matchID] => 4
        [tm] => 2014-01-17 08:44:34
        [playertm] => 2014-01-17 08:44:38
    )

[5] => stdClass Object
    (
        [matchID] => 5
        [tm] => 2014-01-19 08:44:34
        [playertm] => 2014-01-19 08:44:38
    )
)

And am trying to synchronize each array based on the times. I want 4 results to be returned:

  1. The objects in the first array that have a time more recent than the second array
  2. The objects in the second array that have a time more recent than the first array
  3. The objects in the first array that have a 'playertm' more recent than the second array
  4. The objects in the second array that have a 'playertm' more recent than the first array

Some results may not be in each array and will need to be returned, however the array keys will always match.

I am using the 'array_udiff' function and so far have the following:

function tmCompare($a, $b)
{
    return strtotime($a->tm) - strtotime($b->tm);
}
function ptmCompare($a, $b)
{
    return strtotime($a->playertm) - strtotime($b->playertm);
}

$df1 = array_udiff($a, $b, 'tmCompare');
$df2 = array_udiff($b, $a, 'tmCompare');

$df3 = array_udiff($a, $b, 'ptmCompare');
$df4 = array_udiff($b, $a, 'ptmCompare');

Which appears to return the differences, however array [4] is returned in each of the last 2 functions, whereas I only want it to be returned if the time is larger rather than only different.

I have tried

return (strtotime($a->playertm) > strtotime($b->playertm)) ? -1 : 0;

and similar but cannot seem to get the correct results. Am I missing something simple here or going about this wrong?

Edit: here is a quick pastebin to get the code running http://pastebin.com/gRz9v2kz

Thanks for any help.

Thomas
  • 53
  • 5
  • Can we assume that the arrays are sorted by time as in your example? E.g. that the most recent time in the second array will be the time of the last element. – kba Jan 20 '14 at 11:53
  • So to help others, what's the expected outcome for each array? – Ja͢ck Jan 20 '14 at 12:44
  • The [tm] can always be sorted old to new as in the example, however [playertm] may not be. The expected outcome should be 1. [1] [2] 2. [5] 3. [1] [2] 4. [4] [5] If an array is in 1. it shouldn't be in 2. same with 3. and 4. Hope I have explained that well enough. Results that are the same are ignored and only results more recent are returned from each. – Thomas Jan 20 '14 at 12:54

2 Answers2

1

I'm not sure why this happens, but the use of array_udiff() seems counterintuitive. I've rewritten the requirements in two functions to perform the comparison and iterate the array:

function getCompareFunction($field)
{
        return function($a, $b) use ($field) {
                return strcmp($a->{$field}, $b->{$field});
        };
}

function getBigger($a, $b, $compare)
{
        $res = array();

        foreach ($a as $k => $v) {
                if (!isset($b[$k]) || $compare($v, $b[$k]) > 0) {
                        $res[$k] = $v;
                }
        }

        return $res;
}

$biggerTime = getCompareFunction('tm');
$biggerPlayerTime = getCompareFunction('playertm');

print_r(getBigger($a, $b, $biggerTime)); // [1, 2]
print_r(getBigger($b, $a, $biggerTime)); // [4, 5]
print_r(getBigger($a, $b, $biggerPlayerTime)); // [1, 2]
print_r(getBigger($b, $a, $biggerPlayerTime)); // [4, 5]
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Thank you for this beautiful solution. This is a whole new way of looking at it and works exactly as planned. I originally starting looking at this slightly similar with a lot of if statements / foreach's but was not aware of strcmp. – Thomas Jan 20 '14 at 16:40
0

i hope, it will be easy if you can re construct the array in the following structure hence you can make 4 combination out of two objects. and you can sort them as u want

[1] => stdClass Object
    (
        [matchID] => 1

        [tm] =>08:55:13
        [td] =>2014-01-16
        [playertm_date] => 2014-01-16
        [playertm_time] => 08:55:14

    )

one more alternative solution is Json

Vivian
  • 105
  • 6