// your original arrays of integers
$pairs = array(
array(800, 1100),
array(1500, 1600),
array(1900, 2100)
);
// first, normalize the whole thing into a giant list of integers that
// are included in the array pairs, combine and sort numerically
$numbers_in_pairs = array();
foreach($pairs as $set) {
$numbers_in_pairs = array_merge($numbers_in_pairs, range($set[0], $set[1]));
}
sort($numbers_in_pairs);
// find the min
$min = $numbers_in_pairs[0];
// find the max
$max = $numbers_in_pairs[count($numbers_in_pairs)-1];
Find the array difference
// create an array of all numbers inclusive between the min and max
$all_numbers = range($min, $max);
// the numbers NOT included in the set can be found by doing array_diff
// between the two arrays, we need to sort this to assure no errors when
// we iterate over it to get the maxes and mins
$not_in_set = array_diff($all_numbers, $numbers_in_pairs);
sort($not_in_set);
Metadata about the sets we'll use later:
// gather metadata about the numbers that are not inside the set
// $not_in_set_meta['min'] = lowest integer
// $not_in_set_meta['max'] = highest integer
// $not_in_set_meta['mins'] = min boundary integer
// $not_in_set_meta['maxes'] = max boundary integer
$not_in_set_meta = array();
for($i=0;$i<count($not_in_set);$i++) {
if ($i == 0) {
$not_in_set_meta['min'] = $not_in_set[$i];
$not_in_set_meta['mins'][] = $not_in_set[$i];
} else if ($i == count($not_in_set)-1 ) {
$not_in_set_meta['max'] = $not_in_set[$i];
$not_in_set_meta['maxes'][] = $not_in_set[$i];
} else {
// in the event that a number stands alone
// that it can be BOTH the min and the max
if (($not_in_set[$i+1] - $not_in_set[$i]) > 1) {
$not_in_set_meta['maxes'][] = $not_in_set[$i];
}
if (($not_in_set[$i] - $not_in_set[$i-1]) > 1) {
$not_in_set_meta['mins'][] = $not_in_set[$i];
}
}
}
Final output:
// The final variable which we'll dump the ranges not covered into:
$non_sets = array();
while(count($not_in_set_meta['mins']) > 0 && count($not_in_set_meta['maxes'])) {
$non_sets[] = array(array_shift($not_in_set_meta['mins']),
array_shift($not_in_set_meta['maxes']));
}
// print it out:
print var_export($non_sets);
Result:
array (
0 =>
array (
0 => 1101,
1 => 1499,
),
1 =>
array (
0 => 1601,
1 => 1899,
),
)
?>