Johnny
Johnny

Reputation: 851

check array against each other, to determine response

So, I have an array that has 6 variables in it that I need to check against each other.. to determine what to return to the script calling the function.. All fields are of the datetime type from the database they are derived from.

the fields: in1 out1 in2 out2 in3 out3

Array:

Array(
  'in1' => '2012-04-02 10:00:00), 
  `out1` => '2012-04-02 14:00:00`,
  `in2` => '2012-04-02 14:30:00`,
  `out2` => '2012-04-02 18:00:00`,
  `in3` => NULL,
  `out3` => NULL
)

the response:

clocked_in or clocked_out

What I need to figure out is, the best way to determine if the user is clocked in or clocked out by checking against this array..

so, if in1, out1 and in2 are not NULL then the user would be clocked in.. if in1 is not NULL but out1 is NULL then the user would be clocked out, etc.. Anyone have any ideas on the easiest way to achieve this without too many if statements?

[WHAT WORKED]

for ($i=1; $i <= 3; $i++) {
    if ($entities["in$i"] != NULL) {
        $ents = "clocked_in";
        if ($entities["out$i"] != NULL) {
            $ents = "clocked_out";
        }
        if ($entities["out3"] != NULL) {
            $ents = "day_done";
        }
    }
}

Upvotes: 0

Views: 179

Answers (3)

pp19dd
pp19dd

Reputation: 3633

Here's a more stylish way of doing it, without nests:

# the fields as array $a: in1 out1 in2 out2 in3 out3

function is_clocked_in( $a ) {
    $c = (count(array_intersect( $a, array(null) ))) % 2;
    return( $c ? true : false );
}

Theory behind this is that number of null fields gets returned by array_intersect; after that, you find out it that number is even or odd, which implies the clocked-in/out state. Example uses "t" to signify a non-null value, but it's meant to be a string timestamp.

var_dump( is_clocked_in( array( null, null, null, null, null, null ) ) );   // f
var_dump( is_clocked_in( array( "t", null, null, null, null, null ) ) );    // T
var_dump( is_clocked_in( array( "t", "t", null, null, null, null ) ) );     // f
var_dump( is_clocked_in( array( "t", "t", "t", null, null, null ) ) );      // T
var_dump( is_clocked_in( array( "t", "t", "t", "t", null, null ) ) );       // f
var_dump( is_clocked_in( array( "t", "t", "t", "t", "t", null ) ) );        // T
var_dump( is_clocked_in( array( "t", "t", "t", "t", "t", "t") ) );          // f

Upvotes: 1

Matt Moore
Matt Moore

Reputation: 581

What you should do is treat them as pairs. You should loop through your array two at a time checking to see if the clock in is set, and if so, is the clock out set. Update a variable along the way to make sure.

$clocked = '';
for($i=0; $i <= sizeOf($arr); $i+2) // $arr is your array of clock in and outs
{
  if(arr[$i] != NULL)
  {
      // Our Clock In is Not Null and Our Clock Out is.. meaning we're clocked in.
      if(arr[$i+1] == NULL) // check clock out
      {
         $clocked =  "clocked in";
         break; //Break out so we don't check the other pairs because we know we're clocked in.
      }
      else //Clock Out Exists, so far we're clocked out.
      {  
         $clocked = "clocked Out"; // We can't break here. There might be more clock in/out pairs left to check.
      }//end clock out check
   }// end clock in check
}// end for loop

echo $clocked;

Its kinda rough as I wrote this up pretty quickly. I apologize if there are any syntax errors but this is the basic concept I'd use.

Upvotes: 1

Dan Lugg
Dan Lugg

Reputation: 20612

Perhaps a solution is at the schema level; you could modify the database to be an activity log, instead of using a concrete series of columns:

CREATE TABLE IF NOT EXISTS `mydb`.`Occurrence` (
  `ID` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `OccurredOn` DATETIME NOT NULL ,
  `Type` ENUM('IN','OUT') NOT NULL ,
  PRIMARY KEY (`ID`) )
ENGINE = InnoDB

(forgive the brevity)

Now you can support an arbitrary number of clock-in/out occurrences, in the event requirements change.

Finding the state of a user is just selecting the most recent occurrence record, and checking the Type field.

You can validate at the application level, such that if the most recent occurrence state is IN, then you can only insert an OUT, and vice versa.

Use a trigger to auto populate the DATETIME field, or use TIMESTAMP with CURRENT_TIMESTAMP as the default (though I forget the specifics of that)

Upvotes: 0

Related Questions