0

I am writing a simple PHP page reporting results from various sensors. Since the number of sensors and their locations will vary I need to account for that in my code.

$Location_Array = array('Sanding', 'Outside');

foreach($Location_Array as $Locations) {

${"Time_Array_" . $Locations} = array();//Array data fed via array_push via mysql query- clipped 

}

$diff = array_diff(${"Time_Array_" . $Location_Array[0]}, ${"Time_Array_" . $Location_Array[1]});//This is the problem line - It does work

As you can see my Time_Array_LOCATION is an array that is created via an array of locations. The locations will be set by the end user via a settings file. The code does work but each location would have to be manually put into array_diff. The sensors report at specific times and if one fails to report all of the arrays will have that key/value removed. I need to have it compare all of the arrays dynamically from the Location_Array.

Like:

$diff = array_diff($Time_Array_Sanding, $Time_Array_Outside, $Time_Array_ANOTHER);

I figure it is something simple and I am just overlooking it. I thought of looping it but that returns the values not the array variable name etc... I hope this makes sense.

Thanks in advance for the help.

additional info:

The arrays are nothing more than MySQL time stamps. The times just have to match. The data is (09-20-2016 9:00, 09-20-2016 9:30) and so on. If one doesn't have the 9:00 time stamp. I drop the data for that time on all of the arrays.

$date = $row["date_time"];
$dt = substr($date, 5, 11);
array_push(${"Time_Array_" . $Locations}, $dt);
3
  • Can you give a working example with data in the individual arrays, sowe can run the code and see some data produced in $diff? And then specify which outcome you you desire? Commented Sep 20, 2016 at 19:22
  • As you want to drop things which don't occur in all arrays, shouldn't you use array_intersect instead of array_diff? Commented Sep 20, 2016 at 20:43
  • Array_intersect is an option but I was using the difference in other parts of the program. But still the problem would exist of how to put the array arguments in as the dynamic list/array of locations which is what I can't get past. I had thoughts of how you can pass an array to a function like: function takes_array ($array). I appreciate your help. Commented Sep 20, 2016 at 21:37

1 Answer 1

1

I would suggest to store your data in one super-array, instead of distinct variables. It will allow you to pass all arrays to standard PHP functions via call_user_func_array:

$Time_Arrays = []; // Will be a 2D array -- the "super-array".

// You would fill up this data structure from the database, with something like:
/*
while ($row = $pdo->fetch()) {
    // Assuming there is:
    // - a column "type" which can have values "Sanding", "Outside", ...
    // - a column "time_stamp" which has the date/time value to store:
    $Time_Arrays[$row["type"]][] = $row['time_stamp'];
}
*/

// Since I don't have the database, here are some sample data.
// Note that only 2 date/time values are common to all:
$Time_Arrays["Sanding"] = ['09-20-2016 9:00', '09-20-2016 9:30', '09-20-2016 10:00', '09-20-2016 10:30'];
$Time_Arrays["Outside"] = ['09-20-2016 9:00', '09-20-2016 9:30', '09-20-2016 13:00', '09-20-2016 10:30'];
$Time_Arrays["Another"] = ['09-20-2016 9:00', '09-20-2016 11:30', '09-20-2016 10:00', '09-20-2016 10:30'];

// The trick with `call_user_func_array`: merge all sub-arrays together into one array,
// and then remove duplicates from it:
$merged = array_unique(call_user_func_array('array_merge', $Time_Arrays));

// Same trick to get intersection (only values that occur in all sub-arrays):
$intersected = call_user_func_array('array_intersect', $Time_Arrays);

// Finally get the overall difference (values that do not occur in all sub-arrays):
$diff = array_diff($merged, $intersected);

// Show the results
echo "Merged (all values):\n";
print_r($merged);
echo "Intersected (common values only):\n";
print_r($intersected);
echo "Diff (non-common values only):\n";
print_r($diff);

Output of this script is:

Merged (all values):
Array
(
    [0] => 09-20-2016 9:00
    [1] => 09-20-2016 9:30
    [2] => 09-20-2016 10:00
    [3] => 09-20-2016 10:30
    [6] => 09-20-2016 13:00
    [9] => 09-20-2016 11:30
)
Intersected (common values only):
Array
(
    [0] => 09-20-2016 9:00
    [3] => 09-20-2016 10:30
)
Diff (non-common values only):
Array
(
    [1] => 09-20-2016 9:30
    [2] => 09-20-2016 10:00
    [6] => 09-20-2016 13:00
    [9] => 09-20-2016 11:30
)

See it run on eval.in.

Note

Once you get how call_user_func_array works, it would be tempting to do this as a short-cut:

$diff = call_user_func_array('array_diff', $Time_Arrays);

But that will not give the desired result, as it only returns the values from the first sub-array that are not in any of the others, while you would also need the values that are not in the first but do occur in one of the other sub-arrays. The above code overcomes this by first getting the merge of all sub-arrays.

Sign up to request clarification or add additional context in comments.

1 Comment

That will work out. Few minor changes to fit into my program but all is well. Thanks for your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.