0

I have an array with a whole bunch of badges. I have 3 variables that come from the database. I need some idea of how I can calculate the position of my $current variable to the $start and $end variables and then output as an int for a %.

Example:

$data = array(
     ['a','b','c'],
     ['d','e']
);

$start = 'b';
$current = 'c';
$end = 'e';

*Some maths equation to return position value?*

The only idea I have is I probably can count somehow how many variables are between $start and $end and somehow subtract the position of $current?

Update

I tried your code but I think I messed up somewhere:

// Progress Bar configurations
$data = array(
        array('diamond_V','diamond_IV','diamond_III','diamond_II','diamond_I'),
        array('platinum_V','platinum_IV','platinum_III','platinum_II','platinum_I'),
        array('gold_V','gold_IV','gold_III','gold_II','gold_I'),
  array('silver_V','silver_IV','silver_III','silver_II','silver_I'),
  array('bronze_V','bronze_IV','bronze_III','bronze_II','bronze_I')
);

$start = $start_rank;
$current = $current_rank;
$end = $finish_rank;

foreach($data as $key => &$value){
$value = implode(",", $value);
}
$dataimplode = implode(",", $data);

$key = array_search($current, $dataimplode);
var_dump($key);
4
  • Take a look at this : w3schools.com/php/func_array_search.asp Commented Oct 28, 2015 at 8:52
  • What would your expected outcome be in this case? 3 since it's the third value? Commented Oct 28, 2015 at 8:52
  • Are the arrays of different length due to the badges being related in some way? i.e. ['a','b','c'] is: 'dibdib1' => ['a','b','c']? imo, If your array index was text then it would be easier to position at $current. Commented Oct 28, 2015 at 10:52
  • @RyanVincent correct yes each array is grouped as related Commented Oct 28, 2015 at 12:01

4 Answers 4

0

Try following steps

  1. implode your existing array so that it looks like array('a,b,c,d,e')
  2. To do this fist implode the inner arrays in your $data so that it becomes array(['a,b,c'],['d,e']) and then implode this array it would give you an array('a,b,c,d,e')
  3. once you get this then using $key = array_search($value, $array); you can get index of your values "b","c","e" = "2","3","5" respectively (say these numbers are saved in variables $start, $current and $end respectively)
  4. and since you have 3 numeric values now you can easily find the % of "3" by the formula (($current-$start)/($end-$start))*100

Implode $data using following code snippet

$data = array(
    array("a","b","c"),
    array("d","e","f")
);
foreach($data as $key => &$value){
    $value = implode(",", $value);
}
$dataimplode = explode(",",(implode(",", $data)));
print_r($dataimplode);
Sign up to request clarification or add additional context in comments.

4 Comments

If I implode data should it already do it right or how would I actually implode each one inside data?
No directly imploding $data wont work run a foreach loop on data and then implode the data Look at the updated answer after 5 minutes
I will give this a shot today and ill update the result and mark it if it works properly
Replace implode(",", $data) with $dataimplode = explode(",",(implode(",", $data)));. I have updated my answer too.
0

You could do the following :

First get the position of every items :

  • $start should be 0
  • $current with array_search()
  • $end with count()

then once your 3 vars are numbers it's time to do some maths.

($current - $start) / ($end - $start )

Will give you the percentage, even if you're using negative numbers (as long as $end > $current > $start).

1 Comment

can count() be used to not just count the entire array but between certain values?
0

The following function will return an array containing (i,j) meaning the value $needle can be found on $haystack[i][j]. This function supports only a cascade of 2 arrays max, e.g.: array(array()).

function recursive_array_search($needle,$haystack) {
    foreach($haystack as $key=>$value) {
        $some=array_search($needle,$value);
        if(is_array($value) && $some !== false){
            return array($key, $some);
        }
    }
    return false;
}

The following will give you the total index given the (i, j) and the $data array. This function supports only a cascade of 2 arrays max, e.g.: array(array()).

function gettotalindex($index, $array)
{
    $j = 0;
    for($i=0; $i<$index[0]; $i++)
    {
        $j += count($array[$i]);
    }
    $j += $index[1];
    return $j;
}

You can use both of these functions this way:

$start = gettotalindex(recursive_array_search('b', $data), $data);

I've joined them, though, so you'll be able to use recursive_total_index('b', $data) and get the total index and made it fully recursive, supporting an unlimited* number of cascades:

function recursive_total_index($needle, $haystack) {
    $index = 0;
    if(!is_array($haystack)) return false;
    foreach($haystack as $key=>$value) {
        $index += ($key>0 ? count($haystack[$key-1]) : 0);
        $some = recursive_total_index($needle,$value);
        if(is_array($value) && $some !== false){
            return $index+$some;
        }
        else if(!is_array($value) && $needle===$value)
        {
            return $key;
        }
    }
    return false;
}

Example of use:

$data = array( ['a','b'], ['c','d'], array(['e','f'],['g','h'], array(['i','j'])));
echo recursive_total_index('i', $data);    

*Outputs 8*

Then just subtract and do what you want.

1 Comment

But can the above return the position as an int or is it only for finding if it exists.
0

I don't know much about your data structure, but a generic solution would be something with nested loops:

$i = 0;
$startPos = -1;
$endPost = -1;
$currentPos = -1;

foreach ($data as $row) {
    foreach ($row as $item) {
        if ($item == $start) $startPos = $i;
        if ($item == $current) $currentPos = $i;
        if ($item == $end) $endPos = $i;
        
        $i++;
    }
}

Using this code would give you and unique index of each item in the array. The calculation of the distance is then just some subtraction.

Comments

Your Answer

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