我有一个数组:
array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
我想获得此数组的第一个元素。预期结果:字符串 apple
一个要求:它不能通过引用传递来完成,所以array_shift
不是一个好的解决方案。
我怎样才能做到这一点?
&$array
用作参数。
我有一个数组:
array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
我想获得此数组的第一个元素。预期结果:字符串 apple
一个要求:它不能通过引用传递来完成,所以array_shift
不是一个好的解决方案。
我怎样才能做到这一点?
&$array
用作参数。
Answers:
原始答案,但代价昂贵(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];
list()
和reset()
是我的意见好得多的解决方案。
正如Mike指出的(最简单的方法):
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
echo reset($arr); // Echoes "apple"
如果要获取密钥:(重置后执行)
echo key($arr); // Echoes "4"
从PHP的文档中:
混合 重置(array &$ array);
描述:
reset()将数组的内部指针后退到第一个元素,并返回第一个数组元素的值;如果数组为空,则返回FALSE。
foreach
对主题数组执行此操作,则将其弄糟。
foreach
将复制它循环通过的数组。
key($arr)
,您会得到'4'(添加到答案中)
reset()
。2)不,foreach不会创建数组的副本!!!它只会创建自己的指针(甚至不创建现有指针的副本-也很容易检查,next()
在foreach之前调用)。
$first_value = reset($array); // First element's value
$first_key = key($array); // First element's key
current($array)
根据PHP手册,您可以获取数组的第一个元素。
每个数组都有一个指向其“当前”元素的内部指针,该指针被初始化为插入该数组的第一个元素。
因此,它一直有效,直到您重新放置了数组指针为止,否则必须重置数组。
current($array)
仅当数组指针“当前”指向第一个元素时才有效,否则reset($array)
将是必需的。
current()
不再需要参考,尽管PHP文档没有反映出这一点。因此,我认为这已成为最佳解决方案。
您可以使用语言构造“列表”获得第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键入的订单,通常不为0。正如@Sergiy所说,array_values()可以解决此问题,但是会降低代码的效率和(更重要的是)可读性。
PHP 5.4+:
array_values($array)[0];
$array_values = array_values($array); $value = $array_values[0];
PHP 7.3添加了两个函数,可直接获取数组的第一个和最后一个键,而无需修改原始数组,也无需创建任何临时对象:
除了在语义上有意义之外,这些函数甚至都不会移动数组指针(就像foreach
那样)。
有了键,就可以直接通过键获取值。
$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;
假设:
$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
只需使用:
$array[key($array)]
获得第一个元素或
key($array)
获得第一把钥匙。
或者,如果您要删除第一个链接,则可以取消链接。
current
呢?
某些阵列不工作与功能,如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;
}
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;
}
为了记录,这是我的另一个答案,是数组的最后一个元素。
保持简单!这里有很多正确的答案,但是为了最大程度地减少所有的混乱,这两个工作并减少了很多开销:
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()
传递非引用时也不会出错。前提是指针仍处于开始状态。
next()
,end()
或其他任何功能修改阵列的内部指针。在我的示例中,current()
由于内部指针不在数组的范围内,因此返回null。但这也可能“虚拟地”指向任何/随机元素。
$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()
函数不复制整个数组要有效得多。
一种笨拙的方法是:
$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_values($arr)[0]
获取最后一个元素
array_reverse($arr)[0]
这些工作大部分!但是可以进行快速单行(资源较少)的调用:
$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)
最合适。
我认为使用array_values将是您最好的选择。您可以从该函数的结果返回索引零处的值以获取“ apple”。
这对游戏来说有点晚了,但是我遇到了一个问题,我的数组在其中包含作为子元素的数组元素,因此我不能只获得第一个数组元素的字符串表示形式。通过使用PHP的current()
功能,我对此进行了管理:
<?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...
?>
感谢所有当前的解决方案帮助我获得了这个答案,希望这对某人有所帮助!
为您提供两种解决方案。
解决方案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]];
在现实世界中,这并不是那么简单的反应。假设我们有一些可能的响应示例,您可以在某些库中找到这些示例。
$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
。
我想象作者只是在寻找一种从某个函数(例如mysql_fetch_row)获取数组后获取数组第一个元素而不生成STRICT的方法“仅应通过引用传递变量”。
如果是这样,这里描述的几乎所有方法都将得到此消息...,其中一些方法会使用大量额外的内存来复制数组(或数组的一部分)。避免这种情况的一种简单方法是在调用以下任何函数之前直接内联分配值:
$first_item_of_array = current($tmp_arr = mysql_fetch_row(...));
// or
$first_item_of_array = reset($tmp_arr = func_get_my_huge_array());
这样,您既不会在屏幕上也不会在日志中看到STRICT消息,也不会创建任何其他数组。它适用于索引和关联数组。
我喜欢“列表”示例,但“列表”仅适用于作业的左侧。如果我们不想分配变量,我们将被迫组成一个临时名称,该名称充其量会污染我们的范围,而最糟糕的是会覆盖现有值:
list($x) = some_array();
var_dump($x);
上面的代码将覆盖$ x的任何现有值,并且只要该作用域处于活动状态(此函数/方法的末尾,或者如果我们位于顶层,则永久保留),$ x变量就会徘徊。可以使用call_user_func和匿名函数来解决此问题,但这很笨拙:
var_dump(call_user_func(function($arr) { list($x) = $arr; return $x; },
some_array()));
如果我们使用这样的匿名函数,即使它们使用了按引用传递,我们实际上也可以避免使用reset和array_shift。这是因为调用函数将绑定其参数,并且这些参数可以通过引用传递:
var_dump(call_user_func(function($arr) { return reset($arr); },
array_values(some_array())));
但是,这实际上是多余的,因为call_user_func将在内部执行此临时分配。这使我们可以将按引用传递函数视为按值传递,而不会出现任何警告或错误:
var_dump(call_user_func('reset', array_values(some_array())));
尝试这个:
$fruits = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($fruits)."\n";