Say I have an $input
array, that contains something like this :
array
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 => string 'c' (length=1)
3 => string 'd' (length=1)
4 => string 'e' (length=1)
5 => string 'f' (length=1)
6 => string 'g' (length=1)
7 => string 'h' (length=1)
8 => string 'i' (length=1)
9 => string 'j' (length=1)
I want to get an $output
array, that would contain this :
array
0 => string 'a' (length=1)
1 => string 'c' (length=1)
2 => string 'e' (length=1)
3 => string 'g' (length=1)
4 => string 'i' (length=1)
The $output
array contains half the values that were in $input
; those that had even numbered keys in the input; the first one is kept, second one is not, third one is, and so one...
(Note: the keys are not preserved ; only the values are important)
How could I do that ? Keeping only one on two values of the array ?
I have already tried some ideas, and already have a couple different solutions :
First idea: iterate over the input array, and copy the interesting values to the output array:
$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
$output = array();
$nbr = count($input);
for ($i = 0 ; $i < $nbr ; $i += 2) {
$output[] = $input[$i];
}
var_dump(array_values($output));
Second idea: iterate over the array, and unset
what I don't want to keep:
$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
$output = $input;
$nbr = count($input);
for ($i = 1 ; $i < $nbr ; $i += 2) {
unset($output[$i]);
}
var_dump(array_values($output));
Third idea: use a combinaison of array_flip
, range
, array_diff_key
, ... :
$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
$output = array();
$keys_to_exclude = array_flip(range(1, count($input)-1, 2));
$output = array_diff_key($input, $keys_to_exclude);
var_dump(array_values($output));
Fourth idea: about the same thing, but with array_intersect_key
:
$input = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', );
$output = array();
$keys_to_include = array_flip(range(0, count($input)-1, 2));
$output = array_intersect_key($input, $keys_to_include);
var_dump(array_values($output));
Any other idea ? Even / particularly if it sounds kinda hacky or anything ?
My goal is not to get the most efficient nor simple syntax ; it's just for fun and because I am curious, actually ^^
If the title is not using the right words to describe what I want, don't hesitate to tell ; or edit it :-)
<?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);
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With