Alari Truuts
Alari Truuts

Reputation: 320

array_search returns incorrect position

By searching the community and Googleing I can only see issues with array_search loose search resulting integer 0 to be equalled to a string.

However in my case theres no zero and strict search still doesn't seem to help.

Array:

$data= array(
            "13" => array(
                "start" => array(
                    0 => "36000",
                    1 => "43200",
                ),
                "end" => array(
                    0 => "43200",
                    1 => "50400",
                ),
            ),
            "14" => array(
                "start" => array(
                    0 => "36000",
                    1 => "43200",
                ),
                "end" => array(
                    0 => "43200",
                    1 => "50400",
                ),
            ),
        );

function:

foreach ($data as &$area) {
            foreach ($area['start'] as $key => &$start_time) {
                if (($pos = array_search($start_time, $area['end'], true) !== false)) {
                    $area['end'][$pos] = $area['end'][$key];
                    unset($area['start'][$key]);
                    unset($area['end'][$key]);
                }
            }
        }

desired output:

$data= array(
            "13" => array(
                "start" => array(
                    0 => "36000",
                ),
                "end" => array(
                    0 => "50400",
                ),
            ),
            "14" => array(
                "start" => array(
                    0 => "36000",
                ),
                "end" => array(
                    0 => "50400",
                ),
            ),
        );

what I get instead:

$data= array(
            "13" => array(
                "start" => array(
                    0 => "36000",
                ),
                "end" => array(
                    0 => "43200",
                ),
            ),
            "14" => array(
                "start" => array(
                    0 => "36000",
                ),
                "end" => array(
                    0 => "43200",
                ),
            ),
        );

What I intend to achieve with the above function is to combine the consecutive time slots and as it can be seen, the first matching start time in the end is $data[13]['start'][1] = 43200, which matches with the position ..['end'][0], so therefore I'm expecting the $pos returned to also be 0, but the $pos returned is 1 and the wrong element gets treated.

Problem in detail The $data array is dynamic and will not always be this. Even though the matching $start_time value in "end" array can clearly be found at position 0, the $pos value returned is instead 1.

Have been struggling with this for quite some time now and am unable to find a fault, hope someone else will.

Best,

Alari

Upvotes: 0

Views: 610

Answers (3)

Neal
Neal

Reputation: 3179

This is happening because of operator precedence. !== has more precedence over =. So, in your if statement $pos is effectively getting assigned the result of array_search($start_time, $area['end'], true) !== false which is 1. Just change your if statement to this and it should work

if (($pos = array_search($start_time, $area['end'], true)) !== false) {

Upvotes: 2

David
David

Reputation: 1145

You should try this code, it's simple and work in your case

foreach ( $data as &$item ){
        ksort($item['start']);
        ksort($item['end']);
        if ( $item['start'][1] == $item['end'][0] ){
            $item['end'][0] = $item['end'][1]; 
            unset($item['end'][1]); 
            unset($item['start'][1]); 
        }
    }

Upvotes: 0

Sofiene Djebali
Sofiene Djebali

Reputation: 4508

This should work :

PHP

    foreach ($data as &$area) {
        foreach ($area['start'] as $key => &$start_time) {
            if (($pos = array_search($start_time, $area['end'], true) !== false)) {
                $val = $area['end'][$key];
                unset($area['start'][$key]);
                unset($area['end'][$key]);
                $area['end'][0] = $val;
            }
        }
    }

Upvotes: 0

Related Questions