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

2022-08-30 22:12:36

如何让你得到元素和一个在位置数组在特定位置没有循环。keyvaluen

想象

$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

  • 这本来是解决方案,但我跟随wer,因为我没有使用正键(我真的这在php部分也不公平)

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

大数据集是什么意思:

  • 实际上,当我试图作为这个问题管理PHP中的巨型数组时,我偶然发现了这个问题,所以我正在查看或与1e61e7512M memory limit

我相信像数组这样的东西会做到这一点..但不确定是否存在fseek


答案 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

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


答案 2

你想要的是不可能的。PHP的数组具有按键的高效访问,但通过偏移量没有有效的访问。订单仅作为链表提供,因此您可以期望的最佳效率是O(n)循环,该循环仅通过数组并查找偏移量:

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

如果您希望此操作快速,则必须使用正确的数字和顺序索引数组。