0

I have an incredibly weird request for help here, let me try to explain it as best as possible:

I have an array of items (I've hashed the text as the text isn't important, it's the length I'll be using)

Array
(
    [0] => ##
    [1] => ###
    [2] => ###
    [3] => ###
    [4] => ####
    [5] => ###
    [6] => ####
    [7] => #####
    [8] => ##
    [9] => ###
)

What I need to check is to make sure that the lengths of each value is not more than 1 greater than the length of the previous element. They can decrease in length more than 1, but they can't increase in length more than 1. The above array is valid according to these rules.

The array below, however, would be erroneous (see how element 4's length is 2 greater than 3).

Array
(
    [0] => ##
    [1] => ###
    [2] => ###
    [3] => ###
    [4] => #####
    [5] => ###
    [6] => ####
    [7] => #####
    [8] => ##
    [9] => ###
)

Here is what I have so far:

<?php
$array = array('##','###','###','###','####','###','####','#####','##','###'); // Valid Array
$array = array('##','###','###','###','#####','###','####','#####','##','###'); // Invalid Array
$tmp = 0;
$i = 0;
$valid = true;
foreach($array as $k => $v) {
    if($i>0&&strlen($v)>$tmp&&strlen($v)>($tmp+1)) {
        $valid = false;
    }
    $tmp = strlen($v);
    $i++;
}
echo ($valid) ? 'Array is valid' : 'Array is invalid';
?>

It works, but it's messy as hell and I'm not happy with it at all, anyone have any other suggestions on a better way to check for this?

4 Answers 4

1
for($i = 1; $i < count($array); $i++) {
  if( ( strlen($array[$i - 1]) - strlen($array[$i]) ) > 1) {
    $valid = false;
    break;
  }
}

Notice the start of the loop at 1 to avoid having the -1 index at $i = 0

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

4 Comments

Be careful with the abs, OP stated that negative difference can be > 1.
Whilst this is slightly cleaner, it also returns false when it decreases by more than 1, which is allowed.
I would add break; after $valid = false. Once it's invalid, it cannot become valid anymore.
Excellent, thank you for your help @jaudette, moonwave99, and knittl. I think that's as clean as it's going to get. :)
1

I don't think you can't get much better than this - you can just wrap everything in a function for reusability purpose:

function checkArray($array)
{

  foreach($array as $i => $v)
  {

    if($i==0)
      continue;

    if( ( strlen($v) - strlen($array[$i-1]) ) > 1 ){
      return false;
    }

  }

  return true;

}

1 Comment

Thank you. I agree it would be good to have it in a function so it stops once it finds it invalid. I'm going to accept @jaudette's answer due to it using a for look and both accessing the $array rather than $v. Never know, the keys may become a bit messed up. Thank you for your help though :)
1

Off the top of my head I'd probably change the loop to:

foreach ($array as $k => $v) {
    if ($k == 0) {
        continue;
    }
    if ((strlen($v) - strlen($array[$k - 1])) > 1 ) {
        $valid = false;
        break;
    } 
}

Probably best to stick it in a function too. Edit - exactly like moonwave99 has done in fact.

Comments

0

Using current() and each() allows for arrays with any sort of key and doesn't depend on the first key being 0.

   function arr_is_valid(array $arr) {
        $last_len = strlen(current($arr));
        while (list($k,$v) = each($arr) {
          $cur_len = strlen($v);
          if(1 < $cur_len - $last_len) return false;
          $last_len = $cur_len;
        }
        return true;
    }

$valid = arr_is_valid($my_array);

Comments

Your Answer

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