Home > Back-end >  Select a value from an array based on another array in php
Select a value from an array based on another array in php

Time:10-29

I have two arrays, percentiles and percentile_bounds and another int value total_score. Given the total score, I want to return the percentile in which this value is. Ie. I want to return a value from percentiles which corresponds to placing the total_score within the percentile_bounds. In python, I would do:

import numpy as np

percentiles = np.array([ 0,  5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95])
percentile_bounds = np.array([ 84, 104, 109, 115, 120, 123, 125, 127, 129, 132, 135, 136, 137, 139, 141, 145, 148, 151, 155, 159])

# example 1
total_score = 130
print(percentiles[np.where(percentile_bounds==(percentile_bounds[percentile_bounds<total_score][-1]))])
# 40

# example 2
total_score = 153
print(percentiles[np.where(percentile_bounds==(percentile_bounds[percentile_bounds<total_score][-1]))])
# 85

# example 3
total_score = 100
print(percentiles[np.where(percentile_bounds==(percentile_bounds[percentile_bounds<total_score][-1]))])
# 0

and I found a way in PHP (function sources: 1, 2) but it is very clumsy and long:

<?php
// Example 4
$total_score = 120;

$percentile_bounds = [84, 104, 109, 115, 120, 123, 125, 127, 129, 132, 135, 136, 137,139, 141, 145, 148, 151, 155, 159];
       
$percentiles = [0,  5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95];

// get the last element from percentile_bounds which is less than total_score
$value = end(array_filter($percentile_bounds, function ($x) use ($total_score) { return $x < $total_score; }));

// find its index
$key = array_search($value, $percentile_bounds);

// find the corresponding value in percentiles
echo "percentile: $percentiles[$key]";
// 15

Is there a better way of selecting the element from one array (percentiles) based on a position of an element (total_score) in the other array (percentile_bounds)?

Thanks

Note: it is not a duplicate of this.

Clarification: For total_score<=84 the result should be 0 (based on how percentiles work) but it also should not happen. In the code above I do not deal with this condition so it's ok not to but if the solution does, the better :). Thanks @jspit for pointing it out!

CodePudding user response:

foreach would be more readable and performant approach compared to array_filter

$total_score = 153;

$percentile_bounds = [84, 104, 109, 115, 120, 123, 125, 127, 129, 132, 135, 136, 137, 139, 141, 145, 148, 151, 155, 159];

$percentiles = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95];

foreach ($percentile_bounds as $key => $bound) {
    if ($bound > $total_score) {
        echo 'percentile: ' . $percentiles[max(0, $key - 1)];
        break;
    }
}

CodePudding user response:

echo $percentiles[max(array_keys(array_filter($percentile_bounds,function ($x) use ($total_score){return $x<$total_score; })))]
  • Related