在没有循环的数组中获取 N 位置的元素

Posted

技术标签:

【中文标题】在没有循环的数组中获取 N 位置的元素【英文标题】:Get Element at N position in an Array without Loop 【发布时间】:2013-02-12 04:24:49 【问题描述】:

如何在没有循环的特定位置获取 n 位置数组的元素 keyvalue

想象一下

$postion = 3; // get array at 3rd position
$array = array(
        "A" => "Four",
        "B" => "twp",
        "C" => "three",
        "D" => "Four",
        "E" => "Five",
        "F" => "Four");


$keys = array_keys($array);
$value = array_values($array);

echo implode(array_slice($keys, $postion, 1)), php_EOL; // Key at 3rd posstion
echo implode(array_slice($value, $postion, 1)), PHP_EOL; // Value at n position

输出

D
Four

方法的问题是

数组的多次复制导致更高的内存使用率

为什么不使用循环

您必须多次获得多个位置.. 循环大型数据集也效率不高

为什么不使用数据库

是的,使用 Redis 等基于内存的数据库可以让生活更轻松,但特别是数组优化

为什么不使用SplFixedArray

这本来是一个解决方案,但我遵循的是因为我没有使用正键(我真的这在 php 部分也不公平)

Fatal error: Uncaught exception 'InvalidArgumentException' 
with message 'array must contain only positive integer keys' 

大数据集是什么意思:

实际上,当我尝试作为这个问题Managing mega Arrays in PHP 时,我偶然发现了这个问题,所以我正在查看1e61e7512M memory limit

我确信像 fseek 这样的数组可以解决问题.. 但不确定是否存在

【问题讨论】:

对不起,我不明白。如果你需要你的数据容器表现得像有序(索引)数组,为什么你必须首先使用关联数组? 您为什么使用array_slice 而不仅仅是$keys[$position] @raina77ow 默认情况下数组是关联的 @jeroen 它是一个关联数组,键是未知的 不,$keys 有数字键,您只需在前面的行中设置:$keys = array_keys($array); 【参考方案1】:

假设 PHP 5.4,带有数组解引用:

echo $array[array_keys($array)[$position]];

在早期版本中,您需要将其分成两行:

$keys = array_keys($array);
echo $array[$keys[$position]];

如果您必须访问多个元素,那么在 5.4+ 中使用两行方法也是值得的,以允许您只调用一次相对昂贵的 array_keys() 函数。此外,取消引用方法假定数组中的特定位置存在,但它可能不存在。将其分解为多个操作将允许您处理该错误情况。

虽然您当然不需要访问密钥,但您可以这样做:

echo array_values($array)[$position];
// or
$values = array_values($array);
echo $values[$position];

编辑

ArrayIterator 类也可以为您执行此操作:

$iterator = new ArrayIterator($array);
$iterator->seek($position);

echo $iterator->key(), " = ", $iterator->current(); // D = Four

这可能是最便宜的方法,假设它不会在您执行此操作时在内存中创建数组的副本(仍在研究此元素),并且可能是多次访问任意键的最佳方法。

【讨论】:

我想,OP 的问题是 array_keys 在他的情况下太贵了——例如,当一个数组包含数百万个项目时。再说一次,我不太明白这一切的用例:您很少需要在代码中处理大量项目而不是 DB。 @raina77ow 更新为使用ArrayIterator,但我不确定这是否会在下面创建一个副本,在这种情况下,您将失去任何可以负担的改进。 @DaveRandom 我仍然认为你作弊了......即使ArrayObject 没有搜索......不错的一个【参考方案2】:

你想要的都是不可能的。 PHP 的数组可以通过键有效访问,但不能通过偏移有效访问。该顺序仅作为链表提供,因此您希望的最佳效率是 O(n) 循环,它只是遍历数组并查找偏移量:

$i = 0;
foreach ($array as $value) 
    if ($i++ === $offset) 
        // found value
    

如果您希望此操作快速进行,则必须使用适当的、数字和顺序索引的数组。

【讨论】:

@DaveRandom Erm...***.com/a/10058358/1229023(以及它的第一条评论)呢? @raina77ow 更多证据***.com/questions/14848910/… @raina77ow 老实说,我更倾向于和PHP core dev guy谁has foreach related commits in the core ;-) @DaveRandom 我明白了。不过,我承认,在这种特殊情况下,我仍然看不出foreach 的性能如何降低:refcount === 1 => no copying 的规则不应该在这里应用于$array 吗?【参考方案3】:

实际上你不需要 $values 数组:

$keys = array_keys($array);

$value_3=$array[$keys[3]];

【讨论】:

【参考方案4】:

我不太理解你的问题,但是如果你需要一个位置的键和元素

$position = 3; // get array at 3rd position
$array = array(
        "A" => "Four",
        "B" => "twp",
        "C" => "three",
        "D" => "Four",
        "E" => "Five",
        "F" => "Four");


$keys = array_keys($array);
$values = array_values($array);

if($values[$position] == "Four" && $keys[$position] == "D") 
    echo "All it's Right!\n";

你不需要为那个任务内爆

【讨论】:

以上是关于在没有循环的数组中获取 N 位置的元素的主要内容,如果未能解决你的问题,请参考以下文章

Matlab:如何在没有循环或内置函数的情况下递归地获取斐波那契序列中的第 N 个元素

javascript 如何获取元素在数组中的位置 key

Vue.js 2 v-for 循环没有获取数组元素

在N个元素的数组中获取K个元素的所有组合问题

如何获取两个数组相同元素

如何用foreach语句中获取数组元素的下标