Home > Mobile >  Occurrence of a number in a range of other numbers
Occurrence of a number in a range of other numbers

Time:05-13

There is an array with numbers:

$array1 = [200, 400, 600, 800, 1500];

And there is a second array :

$array2 = [50, 150, 250, 600, 900, 2000];

How to create ranges from $array1 like this:

$range = [
          range[1, 200],
          range[201, 400],
          range[401, 600],
          range[601, 800],
          range[801, 1500],
          range[1501, 99999] //99999 - as maximum allowed value
];

And how to check which of these ranges includes each element from $array2? Ex:

50 in array 1 - 200 ($range[0])

My attemps to find solution:

 $max = max($array1);
 $min = min($array1);
    
    foreach($array2 as $a) {

        for ($i = 0; $i < count($array1); $i  ) 
         {
            if ($a < $max AND $a > $min)
              {
                $n[$a] = range($min, $array1[$i]);
  
            } elseif ($a > $max) {
                $n[$a] = range($array1[$i], 999999);
               
            } elseif ($p < $min) {
                $n[$a] = range(1, $array1[$i]);
              } else {

                $n[$a] = "Out of range";
            }
        }
    }

But it will work for three numbers, and if there are more...

Desired result:

50 in 1 - 200
150 in 201 - 400
250 in 201 - 400
600 in 401 - 600
900 in 801 - 1500
2000 in 1501 - 99999

CodePudding user response:

My PHP is too rusty to give that a go unfortunately. Here's a JS version though:

const array1 = [200, 400, 600, 800, 1500];
const array2 = [50, 150, 250, 600, 900, 2000];

const ranges = array1
  .concat(array1[array1.length - 1] < 99999 ? 99999 : [])
  .reduce((acc, val, i, { [i - 1]: prev }) => {
    if(!prev && val === 1) return acc;
    const start = (!prev && val !== 1) || prev === 1 ? 1 : prev   1;
    acc.push([start, val]);
    return acc;
  }, []);

console.log('ranges', JSON.stringify( ranges ));

const find_range = (num) =>
  ranges.find(([start, end]) => start <= num && end >= num);

const res = array2.map((num) => {
  const [start, end] = find_range(num);
  return num   ' in '   start   ' - '   end;
});

console.log(res.join("\n"));

I've assumed that you don't need a range array like the one that PHP's range function would give you and that a two value array listing the start and end of the range is sufficient.

.concat(array1[array1.length - 1] < 99999 ? 99999 : []) checks to see if the last value of the array is less than 99999 and adds 99999 to the array that we run reduce over if it is.

If you're not familar with it here's a description of how reduce works. (PHP equivalent (I think): array_reduce.) Of particular note is { [i - 1]: prev } as part of the argument list. It is simply extracting the previous item in the array from the one that we're currently working with.

Does that look like what you were trying to achieve?

EDIT: should I delete this now that JS is no longer asked for in the question?

  •  Tags:  
  • php
  • Related