-3

I have an array that I want to loop through and make it's elements copy the previous elements's value using PHP.

array [
    17 => "x",
    16 => "x",
    15 => "x",
    14 => "108.7000",
    13 => "x",
    12 => "x",
    11 => "x",
    10 => "x",
    09 => "108.2635",
    08 => "x",
    07 => "x",
    06 => "x",
    05 => "x",
    04 => "x",
    03 => "x",
    02 => "x",
    01 => "x",
    00 => "x",
    23 => "x",
    22 => "x",
    21 => "x",
    20 => "x",
    19 => "x",
    18 => "x"
]

For example, the output should be:

array [
    17 => "108.7000",
    16 => "108.7000",
    15 => "108.7000",
    14 => "108.7000",
    13 => "108.2635",
    12 => "108.2635",
    11 => "108.2635",
    10 => "108.2635",
    09 => "108.2635",
    08 => "108.2635",
    07 => "108.2635",
    06 => "108.2635",
    05 => "108.2635",
    04 => "108.2635",
    03 => "108.2635",
    02 => "108.2635",
    01 => "108.2635",
    00 => "108.2635",
    23 => "108.2635",
    22 => "108.2635",
    21 => "108.2635",
    20 => "108.2635",
    19 => "108.2635",
    18 => "108.2635"
]

as you can see keys above 14 became 108.7000, the letter 'x' will always be there, that is how I want to check. I can't get my head around this, maybe I even haven't used the right wording to describe the question.

look at the key 09 it has a value of 108.2635, below that are all x, which means they all should copy 09's value and above 09 until 04 are also x values, which means they also should be 108.2635, key 14 has its own value and above it are again x values which means they should copy 14's value

ershad7
  • 35
  • 11
  • so the `x` point to the closest next value, or closest previos? – Yosef Tukachinsky Apr 11 '20 at 15:15
  • How this ```08 => "x",``` x value is ```108.2635```? – Sajeeb Ahamed Apr 11 '20 at 15:15
  • @YosefTukachinsky no, x is always there, it can be anywhere, basically x means that this element should copy a value that is not x – ershad7 Apr 11 '20 at 15:17
  • x value is replaced by which condition? – Sajeeb Ahamed Apr 11 '20 at 15:18
  • @SajeebAhamed those values you see that are not x, those are available values, and x means that there is no value, values like 108.2635 can appear anywhere – ershad7 Apr 11 '20 at 15:19
  • @SajeebAhamed x value is replaced by the condition to see if the previous element's value is not x and is a number – ershad7 Apr 11 '20 at 15:20
  • 1
    How come the elements above and below 19 both have same value - 108.2635? – EReload Apr 11 '20 at 15:23
  • It's not clear to me. Could you please describe with a real example or it's a real example? – Sajeeb Ahamed Apr 11 '20 at 15:23
  • @EReload look at the key 09 it has a value of 108.2635, below that are all x, which means they all should copy 09's value and above 09 until 04 are also x values, which means they also should be 108.2635, key 14 has its own value and above it are again x values which means they should copy 14's value – ershad7 Apr 11 '20 at 15:28
  • @SajeebAhamed it is a real example – ershad7 Apr 11 '20 at 15:28
  • I'm not sure of what exactly you want but `array prev()` may help you. this answer may also help you -> https://stackoverflow.com/questions/4792673/php-get-previous-array-element-knowing-current-array-key – kaize Apr 11 '20 at 15:36
  • @user3475530 So basically, you are traversing the array in reverse order and if you encounter any 'number', you replace all the 'x' **around it** with that number? – EReload Apr 11 '20 at 15:39
  • @EReload yes, above and below it, if they are not already x – ershad7 Apr 11 '20 at 15:47

2 Answers2

1

Not completely understanding the structure of your array, I can only provide you the method: -

  1. Declare a variable lastNumber with an initial value of "x".
  2. Loop through the array and when you find an actual number ( != "x"), store it in lastNumber.
  3. Replace every subsequent non-numbers ("x") with lastNumber.
  4. Finally, reverse the array and again follow steps 1, 2 and 3.

I know that this is not the most optimised solution, but you can optimise it yourself if you understand what is happening.

As an example, consider an array: -

["x", "x", "x", "34.34", "x", "x", "20.02", "x"]

  • After step 1: -

lastNumber = "x"

  • Step 2 and 3: -

["x", "x", "x", "34.34", "x", "x", "20.02", "x"]

First, lastNumber's value would be "34.34", so all the following "x"'s would be replaced by "34.34": -

["x", "x", "x", "34.34", "34.34", "34.34", "20.02", "x"]

Next, lastNumber's value would be "20.02", so all the following "x"'s would be replaced by "20.02": -

["x", "x", "x", "34.34", "34.34", "34.34", "20.02", "20.02"]

  • Step 4: -

Now, to replace the initial "x"'s with "34.34", perform the above mentioned steps on the array in reversed order.

Feel free to ask any questions.

EReload
  • 199
  • 2
  • 12
1

Try this-

$data = [ '17' => "x", '16' => "x", '15' => "x", '14' => "x", '13' => "108.7000", '12' => "x", '11' => "x", '10' => "x", '09' => "x", '08' => "x", '07' => "x", '06' => "x", '05' => "x", '04' => "x", '03' => "x", '02' => "x", '01' => "x", '00' => "x", '23' => "x", '22' => "x", '21' => "x", '20' => "x", '19' => "x", '18' => "108.2635"];

// Initially set reference as null. i.e. no reference value
$reference = null;
$group = [];

// Reverse the order so that we can traverse from bottom to up
$data = array_reverse($data, true);

// Traverse the array
foreach ($data as $key => $value)
{
    /**
     * If there is no reference by which we exchange the 'x' value
     * then assign keys at an undefined group.
     */
    if ($reference === null && $value === 'x')
    {
        $group['undefined'][] = $key;
    }
    elseif ($reference === null && $value !== 'x')
    {
        /**
         * If reference not yet set but value is not 'x'
         * then set the reference as the non-x value which we find just now.
         * And change the 'undefined' group by newly found non-x value
         */
        $reference = $value;

        if (!empty($group['undefined']))
        {
            $group[$reference] = $group['undefined'];
            unset($group['undefined']);
        }
    }
    elseif ($reference !== null && $value === 'x')
    {
        /**
         * If reference is set and value is 'x'
         * then push into the key into reference group.
         */
        $group[$reference][] = $key;
    }
    elseif ($reference !== null && $value !== 'x')
    {
        /**
         * If reference is not null and value is also not 'x'
         * then change the reference by newly found non-x value
         * and make a new group and push the key into the group
         */
        $reference = $value;
        $group[$reference][] = $key;
    }
}

/**
 * Traverse the group and exchange the 'x' values
 * from the group reference.
 */
foreach ($group as $value => $refs)
{
    foreach ($refs as $key)
    {
        $data[$key] = $value;
    }
}

/**
 * Finally get the original order of the data array
 *
 */
$data = array_reverse($data, true);

print_r($data);
Sajeeb Ahamed
  • 6,070
  • 2
  • 21
  • 30