简体   繁体   中英

Check value at multiple array indexes in PHP

I'd like to check an array of image filenames to see how many consecutive images have the same orientation using PHP.

In the following example, I'd like to know that indexes 1 through 4 have the same orientation OR that there are four consecutive images with the same orientation at the first index.

For reference, "orientation" values are "V" for vertical and "H" for horizontal.

eg,

Array
(
[0] => Array
    (
        [filename] => image0.jpg
        [orientation] => V
    )

[1] => Array
    (
        [filename] => image1.jpg
        [orientation] => H
    )

[2] => Array
    (
        [filename] => image2.jpg
        [orientation] => H
    )

[3] => Array
    (
        [filename] => image3.jpg
        [orientation] => H
    )

[4] => Array
    (
        [filename] => image4.jpg
        [orientation] => H
    )
[5] => Array
    (
        [filename] => image5.jpg
        [orientation] => V
    )
[...]
[n]
}

There has to be a better way than

if ([i]['orientation'] == [i+1]['orientation'])
if ([i]['orientation'] == [i+1]['orientation'] == [i+2]['orientation'])
if ([i]['orientation'] == [i+1]['orientation'] == [i+2]['orientation']  == [i+3]['orientation'])
if ([i]['orientation'] == [i+1]['orientation'] == [i+2]['orientation'] == [i+3]['orientation'] == [i+4]['orientation'])

If I understand the logic you're trying to apply, SplQueue provides all the functionality to solve your problem thoroughly and tidily OOP fashion.

I wrote this up and it tests out fine for me based on the use case you provided.

// your data array
$array = array(
    array("filename"=>"image0.jpg","orientation"=>"V"),
    array("filename"=>"image1.jpg","orientation"=>"H"),
    array("filename"=>"image2.jpg","orientation"=>"H"),
    array("filename"=>"image3.jpg","orientation"=>"H"),
    array("filename"=>"image4.jpg","orientation"=>"H"));


function queue($array) {

    // grab a new SqlQueue object -- http://php.net/manual/en/class.splqueue.php    
    $q = new SplQueue;
    foreach($array as $key=>$val) {
        // if this is the first iteration or the queue object was emptied out
        if ($q->isEmpty()) {
            $q->enqueue($val);
        } else {

            if ($val['orientation'] == $array[$key--]['orientation']) {
                $q->enqueue($val);
                if (($q->count() % 4) == 0) {
                    return $q;
                }
            } else {
                // Dequeue the whole group on interrupt
                while ($q->valid()) {
                   $q->dequeue();
                }
                // ... and start filling the queue, the mismatch as the new pattern
                $q->enqueue($val);
            }
        }
    }
}

$q = queue($array);
echo $q->count();

The data property enqueued() sets is private, so you'll have to make it visibile in your class.

If you're using PHP 5.4+, you can replace that decremented array index call with function array dereferencing, like so:

    if ($val['orientation'] == prev($array[$key])['orientation'] {
    //...

Everything else is pretty standard. The modulus test returns the queue object as soon as it acquires 4 matches in a row, since SplQueue objects enforce sequenced indexed FIFO, and can't be unsequenced. Finally, if matching interrupts before the queue has 4 matches in a row, Spl's Iterators make emptying the queue to start over - beginning with the mismatch (first new pattern.)

That should cover everything...

HTH :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM