tags:

views:

291

answers:

6
+2  A: 

Assuming numeric keys:

foreach ($array as $key => $value) {
    if ($key % 2 != 0) {
        unset($array[$key]);
    }
}


EDIT

Here goes my slightly more insane solution which keeps the index continuous without re-indexing. ;o)

foreach ($array as $key => $value) {
    if (!($key%2)) {
        $array[$key/2] = $value;
    }
}
$array = array_slice($array, 0, ceil(count($array)/2));
deceze
@Pascal (OP): I have to admit this is not so terrifically different from your `for` solution, but I think you covered almost all bases already yourself. Most sane solutions should pretty much only differ in syntactic sugar. :)
deceze
This is what I was going to suggest as well. If keys are not numeric you could perhaps run the array through a function and create a new array of elements with numeric keys. Each element would then be an array of the key/value pair from the original array.The nice thing about the Modulus operator is that it can be used to find all sorts of number of elements. To find every 5th element if ($key % 5 == 0)This means divide by 5 and return remainder. A list 0 through 15 elements would return 0, 5, 10, and 15 each of which return a remainder of 0 when divided by 5. e.g 10/5 = 2 R0.
Gordon Potter
@deceze : yep, you're right, there is no "miracle" AND maintenable solution ^^ But that's were the fun is ;-) Thanks anyway, didn't think about the modulus!
Pascal MARTIN
Note that this version preserves the input keys ( [0] => a [2] => c [4] => e [6] => g [8] => i) , which might well be useful, but doesn't match the specified output. Using array_values($array) on the output would achieve this of course.
therefromhere
I really don't care about the keys in this situation ; but that's good to know in case I need those some day. Thanks!
Pascal MARTIN
A: 

Not necessarily the most efficient method, but since you mentioned that wasn't necessarily a requirement...

flip, filter, then flip back.

<?php
    function even($var)
    {
        return(!($var & 1));
    }

    $input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
    $flipped = array_flip($input);
    $filtered = array_filter($flipped, 'even');
    $output = array_flip($filtered);
?>
Amber
This might produce unexpected/unintuitive results depending on the input. E.g. $input = array('a', 'a', 'b'); -> $output==array('b')
VolkerK
A: 
  function dropHalf($a){
     $f=0;
     foreach($a as $k=>$v)
       if($f = ! $f)
         unset($a[$k]);
     return $a;
  }

That's the smallest version I could think off.

scragar
Aren't you missing something?
deceze
your if statement wont work buddy.
Ayaz Alavi
A: 

create a wrapper function

function getInput($i)
{
     global $input;
     return $input[$i*2];
}

The smallest and most efficient I guess.

Arpit Tambi
It certainly is small, but what's it do?
deceze
yuck, globals! :P
therefromhere
+6  A: 
<?php
$x = range('a', 'f');

$x = array_map('array_shift', 
       array_chunk($x, 2)
     );

var_dump($x);

or another one

<?php
class ArrayEvenIterator extends ArrayIterator {
    public function next() {
     parent::next();
     return parent::next();
    }
}

$x = range('a', 'f');
$x = iterator_to_array(new ArrayEvenIterator( $x ), false);

var_dump($x);

or with a php 5.3 closure (which isn't better than global in this case ;-) )

<?php
$x = range('a', 'f');

$x = array_filter( $x, function($e) use(&$c) { return 0===$c++%2; });

var_dump($x);
VolkerK
Nice ones too! thanks :-) didn't think about using a closure (my mind is not yet used to those in PHP, I guess ^^ (and I can't use PHP 5.3 as much as I'd like :-( ))
Pascal MARTIN
+1 for using closures and for the `iterator_to_array` (that I didn't know of).
Luiz Damim
+2  A: 

If you're using PHP 5.3 or later, or have the SPL extension installed (you will by default on PHP 5), you can use the FilterIterator and ArrayObject classes.

class EvenKeysFilter extends FilterIterator
{
    private function iseven($keyval)
    {
        return (($keyval % 2) == 0);
    }

    public function accept()
    {
        $keyval = $this->getInnerIterator()->key();
        return ($this->iseven($keyval));
    }
}

$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
$inputobj = new ArrayObject($input);   

$evenFilterIter = new EvenKeysFilter($inputobj->getIterator());    
$output = iterator_to_array($evenFilterIter, false);

print_r($output);

(Props to VolkerK for pointing out iterator_to_array())

Which correctly outputs this:

Array
(
    [0] => a
    [1] => c
    [2] => e
    [3] => g
    [4] => i
)
therefromhere
Don't know why, but I think I love this one ! Wouldn't probably use it in an application someone else will have to maintain, but I definitly like it (and didn't think about SPL). Thanks :-) (just a '(' that has to be removed in the accept method, and then it works)
Pascal MARTIN
I agree, SPL is probably overkill for this case, but stuff like RecursiveIteratorIterator is invaluable.
therefromhere
It's just too bad that people (including myself, actually) generally don't use the SPL enough :-(
Pascal MARTIN
+1 for the cleverness use of SPL. I need to pay more attention to it :)
Luiz Damim