我有一个数组:
array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
我想得到这个数组的第一个元素。预期结果:字符串 apple
一个要求:不能通过引用传递来完成,因此 array_shift
不是一个好的解决方案。
我怎样才能做到这一点?
&$array
作为参数。
原始答案,但代价高昂(O(n)):
array_shift(array_values($array));
在 O(1) 中:
array_pop(array_reverse($array));
其他用例等...
如果修改(在重置数组指针的意义上)$array
不是问题,您可以使用:
reset($array);
如果需要数组“副本”,这在理论上应该更有效:
array_shift(array_slice($array, 0, 1));
使用 PHP 5.4+(但如果为空可能会导致索引错误):
array_values($array)[0];
正如迈克指出的(最简单的方法):
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($arr); // Echoes "apple"
如果要获取密钥:(reset后执行)
echo key($arr); // Echoes "4"
混合重置(数组|对象&$array);
描述:
reset() 将数组的内部指针倒回到第一个元素并返回第一个数组元素的值,如果数组为空,则返回 FALSE。
foreach
中执行此操作,您会搞砸的。
foreach
将复制它循环通过的数组。
key($arr)
,您将得到“4”(添加到答案中)
reset()
没有任何影响。 2) 不,foreach 不会创建数组的副本!!!它只创建它自己的指针(甚至不是现有指针的副本 - 它也很容易检查,在 foreach 之前调用 next()
)。
$first_value = reset($array); // First element's value
$first_key = key($array); // First element's key
reset()
将返回 false
,如果您希望数组包含 bool
值,这可能会导致错误。
current($array)
返回数组的第一个元素 according to the PHP manual。
每个数组都有一个指向其“当前”元素的内部指针,该元素被初始化为插入到数组中的第一个元素。
所以它一直有效,直到您重新定位数组指针,否则您将不得不使用 reset()
它将倒回数组并返回数组的第一个元素
According to the PHP manual reset。
reset() 将数组的内部指针倒回到第一个元素并返回第一个数组元素的值。
current()
和 reset()
的示例
$array = array('step one', 'step two', 'step three', 'step four');
// by default, the pointer is on the first element
echo current($array) . "<br />\n"; // "step one"
//Forward the array pointer and then reset it
// skip two steps
next($array);
next($array);
echo current($array) . "<br />\n"; // "step three"
// reset pointer, start again on step one
echo reset($array) . "<br />\n"; // "step one"
current($array)
仅在数组指针“当前”指向第一个元素时才有效,否则需要 reset($array)
。
current()
不再需要参考,尽管 PHP 文档没有反映这一点。所以我认为这已经成为最好的解决方案。
reset()
和 current()
将返回 false
,如果您希望数组包含 bool
值,这可能会导致错误。
$arr = $array = array( 9 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($arr); // echoes 'apple'
如果您不想丢失当前指针位置,只需为数组创建一个别名。
reset()
已经返回第一个元素,因此无需使用 current()
- echo reset($arr)
就足够了
reset()
将返回 false
,如果您希望数组包含 bool
值,这可能会导致错误。
PHP 7.3 添加了两个函数,用于直接获取数组的第一个和最后一个键,无需修改原始数组,也无需创建任何临时对象:
array_key_first
array_key_last
除了在语义上有意义之外,这些函数甚至不移动数组指针(就像 foreach
所做的那样)。
有了键,可以直接通过键获取值。
示例(所有这些都需要 PHP 7.3+)
获取第一个/最后一个键和值:
$my_array = ['IT', 'rules', 'the', 'world'];
$first_key = array_key_first($my_array);
$first_value = $my_array[$first_key];
$last_key = array_key_last($my_array);
$last_value = $my_array[$last_key];
假设数组不能为空,将第一个/最后一个值作为单行:
$first_value = $my_array[ array_key_first($my_array) ];
$last_value = $my_array[ array_key_last($my_array) ];
获取第一个/最后一个值作为单行,默认为空数组:
$first_value = empty($my_array) ? 'default' : $my_array[ array_key_first($my_array) ];
$last_value = empty($my_array) ? 'default' : $my_array[ array_key_last($my_array) ];
$first_value = $my_array[array_key_first($my_array)] ?? null;
您可以使用语言构造“list”获取第 N 个元素:
// First item
list($firstItem) = $yourArray;
// First item from an array that is returned from a function
list($firstItem) = functionThatReturnsArray();
// Second item
list( , $secondItem) = $yourArray;
使用 array_keys
函数,您可以对键执行相同操作:
list($firstKey) = array_keys($yourArray);
list(, $secondKey) = array_keys($yourArray);
list($first_value) = $my_array;
在我看来,这是最好的选择。它没有此处提供的其他答案的问题:没有“矫枉过正”,因为它不复制数组或创建新数组。没有“引用”:数组没有被修改。没有“重置”:没有更改数组内部指针......
int
时才有效,尝试执行 list($firstItem) = array('key1' => 'value1');
会出现错误 Notice: Undefined offset: 0
list($x) = foo();
等同于 $x = foo()[0];
。请注意,这不一定与“获取第一项”相同,因为即使是整数索引数组也可能没有键为 0 的元素。在我的情况下,我正在执行“list($order) = get_order($user) ;"但是“get_order”返回的是由 ID 键入的订单,该 ID 通常不是 0。正如 @Sergiy 所说,array_values() 解决了这个问题,但降低了代码的效率和(更重要的是)可读性。
PHP 5.4+:
array_values($array)[0];
$array_values = array_values($array); $value = $array_values[0];
undefined key 0
,因此请谨慎使用
某些数组不适用于 list
、reset
或 current
等函数。也许它们是“人造”数组——例如,部分实现了 ArrayIterator。
如果您想提取第一个值而不考虑数组,您可以将迭代器短路:
foreach($array_with_unknown_keys as $value) break;
然后,您的值将在 $value
中可用,并且循环将在第一次迭代后中断。这比将可能很大的数组复制到像 array_unshift(array_values($arr)) 这样的函数更有效。
您也可以通过以下方式获取密钥:
foreach($array_with_unknown_keys as $key=>$value) break;
如果您从函数中调用它,只需提前返回:
function grab_first($arr) {
foreach($arr as $value) return $value;
}
认为:
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
只需使用:
$array[key($array)]
获取第一个元素或
key($array)
获得第一把钥匙。
或者,如果您想删除它,您可以取消第一个链接。
current
呢?
function head($array)
{
return reset($array);
}
数组按值传递给函数,reset() 影响数组副本的内部指针,并且它不接触原始数组(注意,如果数组为空,它会返回 false
)。
使用示例:
$data = ['foo', 'bar', 'baz'];
current($data); // foo
next($data); // bar
head($data); // foo
next($data); // baz
此外,这里还有一个替代方案。它的速度非常快,但更有趣。如果数组为空,它可以轻松更改默认值:
function head($array, $default = null)
{
foreach ($array as $item) {
return $item;
}
return $default;
}
作为记录,这里是 another answer of mine,表示数组的最后一个元素。
保持简单!这里有很多正确的答案,但是为了尽量减少所有的混淆,这两个工作并减少了很多开销:
key($array)
获取数组的第一个键
current($array)
获取数组的第一个值
编辑:
关于以下评论。以下示例将输出:string(13) "PHP code test"
$array = array
(
'1' => 'PHP code test',
'foo' => 'bar', 5 , 5 => 89009,
'case' => 'Random Stuff: '.rand(100,999),
'PHP Version' => phpversion(),
0 => 'ending text here'
);
var_dump(current($array));
current
等于当前元素。您必须将指针重置为数组的开头,以确保它实际上位于开头。
只需这样做:
array_shift(array_slice($array,0,1));
我会做 echo current($array)
。
current()
在传递非引用时不会出错。如果指针仍然在开头,则此方法有效。
reset
会产生“只有变量应该通过引用传递”的通知,而 current
不会:Online PHP Editor example of current(array_filter(...));
。
next()
、end()
或任何其他修改数组内部指针的函数的函数接收数组。在我的示例中,current()
返回 null,因为内部指针超出了数组的范围。但它也可能“实际上”指向任何/随机元素。
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
foreach($arr as $first) break;
echo $first;
输出:
apple
PHP 7.3 添加了两个函数,用于直接获取数组的第一个和最后一个键,无需修改原始数组,也无需创建任何临时对象:
array_key_first
array_key_last
“有几种方法可以为 PHP 7.3.0 之前的版本提供此功能。可以使用 array_keys(),但效率可能相当低。也可以使用 reset() 和 key(),但是可能会改变内部数组指针。一个有效的解决方案,不改变内部数组指针,写成polyfill:"
<?php
if (!function_exists('array_key_first')) {
function array_key_first($arr) {
foreach($arr as $key => $unused) {
return $key;
}
return NULL;
}
}
if (!function_exists('array_key_last')) {
function array_key_last($arr) {
return array_key_first(array_reverse($arr, true));
}
}
?>
$myArray = array (4 => 'apple', 7 => 'orange', 13 => 'plum');
$arrayKeys = array_keys($myArray);
// The first element of your array is:
echo $myArray[$arrayKeys[0]];
$array=array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
$firstValue = each($array)[1];
这比 array_values()
高效得多,因为 each()
函数不会复制整个数组。
有关详细信息,请参阅 http://www.php.net/manual/en/function.each.php
because the each() function does not copy the entire array.
+1
一个笨拙的方法是:
$foo = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
function get_first ($foo) {
foreach ($foo as $k=>$v){
return $v;
}
}
print get_first($foo);
reset()
,因为在调用 foreach
之前重置数组指针。
大多数这些工作!但是对于快速单行(低资源)调用:
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo $array[key($array)];
// key($array) -> will return the first key (which is 4 in this example)
虽然这很有效,而且还不错,但也请参阅我的附加答案:https://stackoverflow.com/a/48410351/1804013
current($array)
,它要求数组的内部指针无论如何都位于第一个元素,在这种情况下,echo reset($array)
是最合适的。
利用:
$first = array_slice($array, 0, 1);
$val= $first[0];
默认情况下,array_slice
不保留键,因此我们可以安全地使用零作为索引。
这对游戏来说有点晚了,但是我遇到了一个问题,我的数组包含数组元素作为其中的子元素,因此我不能只获得第一个数组元素的字符串表示形式。通过 using PHP's current()
function,我做到了:
<?php
$original = array(4 => array('one', 'two'), 7 => array('three', 'four'));
reset($original); // to reset the internal array pointer...
$first_element = current($original); // get the current element...
?>
感谢所有当前的解决方案帮助我得到这个答案,我希望这对某人有所帮助!
<?php
$arr = array(3 => "Apple", 5 => "Ball", 11 => "Cat");
echo array_values($arr)[0]; // Outputs: Apple
?>
其他示例:
<?php
$arr = array(3 => "Apple", 5 => "Ball", 11 => "Cat");
echo current($arr); // Outputs: Apple
echo reset($arr); // Outputs: Apple
echo next($arr); // Outputs: Ball
echo current($arr); // Outputs: Ball
echo reset($arr); // Outputs: Apple
?>
为您提供两种解决方案。
解决方案 1 - 只需使用密钥。你还没有说你不能使用它。 :)
<?php
// Get the first element of this array.
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
// Gets the first element by key
$result = $array[4];
// Expected result: string apple
assert('$result === "apple" /* Expected result: string apple. */');
?>
解决方案 2 - array_flip() + key()
<?php
// Get first element of this array. Expected result: string apple
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
// Turn values to keys
$array = array_flip($array);
// You might thrown a reset in just to make sure
// that the array pointer is at the first element.
// Also, reset returns the first element.
// reset($myArray);
// Return the first key
$firstKey = key($array);
assert('$firstKey === "apple" /* Expected result: string apple. */');
?>
解决方案 3 - array_keys()
echo $array[array_keys($array)[0]];
没有人建议使用 ArrayIterator 类:
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
$first_element = (new ArrayIterator($array))->current();
echo $first_element; //'apple'
绕过 OP 的参考规定。
(new ArrayIterator($array))->key()
。请注意,当数组为空时,它会正确返回值和键的 null
(而不是返回像 false
这样的伪值)。不幸的是,它不适用于 Laravel 的 Collection 类,它总是返回 null
我想作者只是在寻找一种方法来在从某个函数(例如 mysql_fetch_row)获取数组的第一个元素后获取它,而不生成严格的“只有变量应该通过引用传递”。
如果是这样,这里描述的几乎所有方式都会收到此消息......其中一些使用大量额外的内存来复制数组(或其中的一部分)。避免它的一种简单方法是在调用任何这些函数之前内联分配值:
$first_item_of_array = current($tmp_arr = mysql_fetch_row(...));
// or
$first_item_of_array = reset($tmp_arr = func_get_my_huge_array());
这样您就不会在屏幕上或日志中看到 STRICT 消息,也不会创建任何额外的数组。它适用于索引和关联数组。
使用 array_keys()
以数字索引数组的形式访问关联数组的键,然后可以再次将其用作数组的键。
解决方案为 arr[0]
时:
(注意,由于带有键的数组是从 0 开始的索引,所以第一个元素是索引 0)
您可以使用一个变量,然后减去一个,以获得您的逻辑,即 1 => 'apple'
。
$i = 1;
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo $arr[array_keys($arr)[$i-1]];
输出:
apple
好吧,为简单起见 - 只需使用:
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo $arr[array_keys($arr)[0]];
输出:
apple
通过第一种方法,不仅是第一个元素,而且可以将关联数组视为索引数组。
我不喜欢摆弄数组的内部指针,但是用 array_keys()
或 array_values()
构建第二个数组也是低效的,所以我通常这样定义:
function array_first(array $f) {
foreach ($f as $v) {
return $v;
}
throw new Exception('array was empty');
}
这在现实世界中并不是那么简单的反应。假设我们有这些可能的响应示例,您可以在某些库中找到这些示例。
$array1 = array();
$array2 = array(1,2,3,4);
$array3 = array('hello'=>'world', 'foo'=>'bar');
$array4 = null;
var_dump('reset1', reset($array1));
var_dump('reset2', reset($array2));
var_dump('reset3', reset($array3));
var_dump('reset4', reset($array4)); // Warning
var_dump('array_shift1', array_shift($array1));
var_dump('array_shift2', array_shift($array2));
var_dump('array_shift3', array_shift($array3));
var_dump('array_shift4', array_shift($array4)); // Warning
var_dump('each1', each($array1));
var_dump('each2', each($array2));
var_dump('each3', each($array3));
var_dump('each4', each($array4)); // Warning
var_dump('array_values1', array_values($array1)[0]); // Notice
var_dump('array_values2', array_values($array2)[0]);
var_dump('array_values3', array_values($array3)[0]);
var_dump('array_values4', array_values($array4)[0]); // Warning
var_dump('array_slice1', array_slice($array1, 0, 1));
var_dump('array_slice2', array_slice($array2, 0, 1));
var_dump('array_slice3', array_slice($array3, 0, 1));
var_dump('array_slice4', array_slice($array4, 0, 1)); // Warning
list($elm) = $array1; // Notice
var_dump($elm);
list($elm) = $array2;
var_dump($elm);
list($elm) = $array3; // Notice
var_dump($elm);
list($elm) = $array4;
var_dump($elm);
如您所见,我们有几种“单线”解决方案在某些情况下效果很好,但并非全部。
在我看来,您应该只使用数组处理该处理程序。
现在谈论性能,假设我们总是有数组,像这样:
$elm = empty($array) ? null : ...($array);
...you would use without errors:
$array[count($array)-1];
array_shift
reset
array_values
array_slice
array_shift
比 reset
快,即比 [count()-1] 快,这三个比 array_values
和 array_slice
快。
list()
和reset()
在我看来是更好的解决方案。