Php 是否保留数组中的偶数元素?

Php 是否保留数组中的偶数元素?,php,arrays,Php,Arrays,假设我有一个$input数组,它包含如下内容: 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

假设我有一个
$input
数组,它包含如下内容:

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)
我想获得一个
$output
数组,该数组将包含以下内容:

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)
$output
数组包含
$input
中一半的值;那些在输入中有偶数键的;第一个是保留的,第二个不是,第三个是,所以一个

(注意:键不保留;只有值才重要)

我怎么能做到?仅保留数组的两个值中的一个?


我已经尝试了一些想法,并且已经有了一些不同的解决方案:

第一个想法:迭代输入数组,并将感兴趣的值复制到输出数组:

$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));
第三个想法:使用组合的
数组翻转
范围
数组差异键
,…:

$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));
第四个想法:关于同样的事情,但是使用
数组\u intersect\u键

$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));
还有别的想法吗?即使/特别是如果它听起来有点像黑客之类的话

我的目标不是获得最有效、最简单的语法;其实,这只是为了好玩,因为我很好奇^^

如果标题没有用正确的词来描述我想要的,不要犹豫,告诉我;或者编辑它(假设数字键为:

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

编辑

我的解决方案稍微有些疯狂,它可以保持索引连续而不重新索引;o)


不一定是最有效的方法,但既然你提到这不一定是一个要求

翻转,过滤,然后翻转

<?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);
?>


这是我能想到的最小版本。

创建一个包装函数

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

我猜是最小也是最有效的。

如果您使用的是PHP5.3或更高版本,或者安装了SPL扩展(默认情况下,您将安装在PHP5上),那么可以使用和类

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

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

var_dump($x);
(用于指出的道具)

哪一个输出正确:

Array
(
    [0] => a
    [1] => c
    [2] => e
    [3] => g
    [4] => i
)

我将反转按位奇数检查,或者使用
array\u filter()
(并使用
array\u values()
)重新索引结果,或者使用经典的
foreach()
循环

代码:()

输出:

array (
  0 => 'a',
  1 => 'c',
  2 => 'e',
  3 => 'g',
  4 => 'i',
)
---
array (
  0 => 'a',
  1 => 'c',
  2 => 'e',
  3 => 'g',
  4 => 'i',
)

在我自己的项目中,我更喜欢将全局变量声明保持在最小值,因此我会使用
array\u filter()

我根据要求编辑了算法的标题和描述。就我个人而言,我会使用第一个想法——这很简单,也很清楚你在做什么。谢谢你的编辑:-)好吧,事实上,“我如何在没有自己循环的情况下做到这一点”是几天前在工作中突然出现的一个问题;我和一位同事考虑过这件事。。。最后,我们使用了“for”解决方案(我给出的第一个):不太有趣,但当有人需要维护我们的代码时,更容易理解——这是我们工作中最重要的事情之一;但是,这仍然是一个有趣的问题,我想我可能会在这里得到一些有趣/有趣的命题^^+1,用于有自己想法的精心设计的问题。你是否遗漏了一些东西?它当然很小,但它有什么作用?这可能会根据输入产生意外/不直观的结果。例如,$input=数组('a','a','b');->$output==array('b')@Pascal(OP):我必须承认这与您的
for
解决方案没有太大区别,但我认为您自己已经涵盖了几乎所有的基础。大多数明智的解决方案应该只在语法上有很大的不同。:)这也是我要建议的。如果键不是数字的,则可以通过函数运行数组,并使用数字键创建一个新的元素数组。然后,每个元素将是来自原始数组的键/值对的数组。模算子的优点在于它可以用来寻找各种数量的元素。若($key%5==0),则查找每5个元素,这意味着除以5并返回余数。列表0到15个元素将返回0、5、10和15,每个元素在除以5时返回0的余数。e、 g 10/5=2 R0。@deceze:是的,你说得对,没有“奇迹”和可维护的解决方案^^^^但这就是乐趣所在;-)无论如何,谢谢你,我没有考虑模数!请注意,此版本保留输入键([0]=>a[2]=>c[4]=>e[6]=>g[8]=>i),这可能很有用,但与指定的输出不匹配。当然,在输出上使用array_值($array)可以实现这一点;但如果有一天我需要的话,知道这一点很好。谢谢不知道为什么,但我想我喜欢这个!可能不会在其他人必须维护的应用程序中使用它,但我绝对喜欢它(并且没有考虑SPL)。谢谢:-)(只有一个“(”必须在accept方法中删除,然后它才能工作)我同意,SPL在这种情况下可能有点过头了,但是像RecursiveIteratorIterator这样的东西是非常宝贵的。遗憾的是,人们(包括我自己)通常没有充分使用SPL:-(+1用于SPL的巧妙使用。我需要更加注意:)也不错!谢谢:-)没有考虑过使用闭包(我的头脑还不习惯PHP中的闭包,我猜^(我不能像我所希望的那样使用PHP5.3:-())+1用于使用闭包和
迭代器数组
(我不知道)。
<?php
$x = range('a', 'f');

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

var_dump($x);
<?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);
<?php
$x = range('a', 'f');

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

var_dump($x);
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);
Array
(
    [0] => a
    [1] => c
    [2] => e
    [3] => g
    [4] => i
)
$array = range('a', 'j');
var_export(
    array_values(
        array_filter(
            $array,
            function($k) {
                return !($k & 1);
            },
            ARRAY_FILTER_USE_KEY
        )
    )
);
echo "\n---\n";
$result = [];
foreach ($array as $index => $value) {
    if (!($index & 1)) {
        $result[] = $value;
    }
}
var_export($result);
array (
  0 => 'a',
  1 => 'c',
  2 => 'e',
  3 => 'g',
  4 => 'i',
)
---
array (
  0 => 'a',
  1 => 'c',
  2 => 'e',
  3 => 'g',
  4 => 'i',
)