Obtenga el primer elemento de una matriz

1072

Tengo una matriz:

array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )

Me gustaría obtener el primer elemento de esta matriz. Resultado esperado: cadena apple

Un requisito: no se puede hacer pasando por referencia , por array_shiftlo que no es una buena solución.

¿Cómo puedo hacer esto?

hsz
fuente
1
¿Qué quieres decir con que no se puede hacer por referencia?
cjk
La función no debería funcionar utilizando &$arraycomo parámetros.
hsz
44
Sospecho que lo que "realmente" quiere decir con "no se puede hacer por referencia", es que su matriz se devuelve dinámicamente desde una base de datos, y no desea pasar la matriz a una variable antes de tomar el primer elemento de eso. Si estoy en lo cierto, entonces la gran mayoría de todas las soluciones que se proporcionan a continuación (incluida la respuesta aceptada) son insuficientes.
cartbeforehorse
¿Solo tiene que obtenerlo u obtenerlo y eliminarlo de la matriz existente?
Jo Smo
Para el uso básico de las matrices, puede revisar este enlace technofusions.com/introduction-to-arrays-in-php
Vikrant Vir Bhalla

Respuestas:

1369

Respuesta original, pero costosa (O (n)):

array_shift(array_values($array));

En O (1):

array_pop(array_reverse($array));

Otros casos de uso, etc.

Si modificar (en el sentido de restablecer los punteros de matriz) de $arrayno es un problema, puede usar:

reset($array);

Esto debería ser teóricamente más eficiente, si se necesita una "copia" de matriz:

array_shift(array_slice($array, 0, 1));

Con PHP 5.4+ (pero puede causar un error de índice si está vacío):

array_values($array)[0];
azulado
fuente
77
+1 para la solución inteligente para evitar modificar la matriz original con array_values ​​()
ChrisR
44
Me sale esto: <b> Normas estrictas </b>: solo las variables deben pasarse por referencia. Buena solución por cierto
Simone
191
¿No es esto un poco exagerado? ¿Qué pasa si la matriz contiene varios miles de elementos? ¿Está justificado crear una matriz completamente nueva solo para obtener su primer elemento? list()y reset()son soluciones mucho mejores para mi opinión.
Martin Dimitrov
33
Estoy de acuerdo. Exceso total y recursos extraordinarios pesados ​​en comparación con una línea que restablece y devuelve el valor actual: restablecer ($ array);
zmonteca
48
-1 Como han dicho los comentaristas anteriores. Me desconcierta que esto tenga 101 votos a favor.
Carreras de ligereza en órbita el
790

Como Mike señaló (la forma más fácil posible):

$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' )
echo reset($arr); // Echoes "apple"

Si desea obtener la clave: (ejecútela después de restablecer)

echo key($arr); // Echoes "4"

De la documentación de PHP :

reinicio mixto (matriz y $ matriz );

Descripción:

reset () rebobina el puntero interno de la matriz al primer elemento y devuelve el valor del primer elemento de la matriz, o FALSE si la matriz está vacía.

lepe
fuente
Aunque se pasa por referencia para restablecer, la matriz original no se modifica. Supongo que esa es la razón por la que hsz no quiere pasarlo por referencia ...
Dennis Jamin
10
El iterador de la matriz se modifica. Si haces esto en un foreachconjunto de temas, lo arruinarás.
Zenexer
2
@Zenexer esto no siempre es (generalmente) cierto. Por lo general, en la práctica, foreachcopiará la matriz que está recorriendo.
Luke Cousins
1
@Angger después del reinicio, puede llamar key($arr)y obtendrá '4' (agregado en la respuesta)
lepe
3
Ni @Zenexer ni Luke Cousins ​​tienen razón: 1) foreach no usa el puntero interno de una matriz; en su lugar, crea su propio puntero. Es fácil verificar el restablecimiento de llamadas dentro de foreach: el bucle seguirá su camino sin ningún efecto reset(). 2) No, foreach NO crea una copia de una matriz !!! Solo crea su propio puntero (ni siquiera una copia de uno existente; también es fácil de verificar, llamando next()antes de foreach).
dmikam
278
$first_value = reset($array); // First element's value
$first_key = key($array); // First element's key
Ijas Ameenudeen
fuente
2
En realidad no lo he probado, pero parece que este enfoque sería el más eficiente.
mason81
44
El único problema es la pregunta sobre el valor, no la clave. Por lo tanto, se debe usar current ($ array) en lugar de key ($ array)
zmonteca
44
@zmonteca $ first_value = reset ($ array); aquí obtiene el valor, la función reset () rebobina el puntero interno de las matrices y devuelve el primer elemento.
S3Mi
1
la mejor respuesta! estaba buscando la equivalencia de key () para obtener el primer valor. ¡Esto ayuda!
Alain Tiemblo
98
$arr = array( 9 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($arr); // echoes 'apple'

Si no desea perder la posición actual del puntero, simplemente cree un alias para la matriz.

yoda
fuente
1
no lo entendiste, ¿qué quieres decir? Funciona bien si la clave de la primera es más grande que las otras.
yoda
29
+1 FYI reset()ya devuelve el primer elemento, por lo que no hay necesidad de usarlo current()- echo reset($arr)debería ser suficiente
Mike
@ Mike, pero es posible que prefiera currentpara resetevitar PHP aviso / error se produce en los casos de referencia, por ejemplo, current(array_filter(...));en 3v4l .
CPHPython
91

current($array)puede obtener el primer elemento de una matriz, de acuerdo con el manual de PHP .

Cada matriz tiene un puntero interno a su elemento "actual", que se inicializa en el primer elemento insertado en la matriz.

Por lo tanto, funciona hasta que haya reubicado el puntero de la matriz, y de lo contrario tendrá que restablecer la matriz.

Tofeeq
fuente
44
No sé por qué esta no fue la respuesta aceptada, ya que responde la pregunta de manera bastante simple y precisa.
relipse
26
current($array)solo funcionará si el puntero de la matriz está "actualmente" apuntando al primer elemento; de lo contrario, reset($array)sería necesario.
Jon
66
Parece que current()ya no requiere una referencia, aunque los documentos PHP no reflejan esto. Así que creo que esta se ha convertido en la mejor solución.
Ryan
@Ryan estuvo de acuerdo, pero esta solución se dio 2 años antes de 2014 en esta otra respuesta de este mismo hilo ... Es extraño que esta oración incompleta haya recibido más votos a favor.
CPHPython
70

Puede obtener el enésimo elemento con una construcción de lenguaje, "lista":

// First item
list($firstItem) = $yourArray;

// First item from an array that is returned from a function
list($firstItem) = functionThatReturnsArray();

// Second item
list( , $secondItem) = $yourArray;

Con la array_keysfunción puede hacer lo mismo para las teclas:

list($firstKey) = array_keys($yourArray);
list(, $secondKey) = array_keys($yourArray);
Sergiy Sokolenko
fuente
2
Esto es exactamente lo que hago: list($first_value) = $my_array;en mi opinión, la mejor opción. No tiene los problemas de las otras respuestas presentadas aquí: no "overkill" porque no copia ni la matriz ni crea una nueva. Sin "referencias": la matriz no se modifica. No "reset": no hay cambios en el puntero interno de la matriz ...
J. Bruni
66
Solución muy elegante, pero arroja un E_NOTICE cuando la matriz está vacía.
Tgr
1
@Mike sí, pero ya no es tan elegante :)
Tgr
13
¿No está mal? Funciona solo si las teclas de matriz son int, intente hacerlo list($firstItem) = array('key1' => 'value1');y obtendrá un errorNotice: Undefined offset: 0
Marco Demaio
12
Para aclarar: list($x) = foo();es equivalente a $x = foo()[0];. Tenga en cuenta que esto no es necesariamente lo mismo que "obtener el primer elemento", ya que incluso una matriz indexada con enteros puede no tener un elemento con la clave 0. En mi caso, estaba haciendo "list ($ order) = get_order ($ user) ; " pero "get_order" estaba devolviendo pedidos marcados por su ID, que generalmente no era 0. Como dice @Sergiy, array_values ​​() corrige esto, pero resta valor a la eficiencia y (más importante) legibilidad del código.
Warbo
55

PHP 5.4+:

array_values($array)[0];
Samer Ata
fuente
Esto es para las personas geniales que dirigen lo último y lo mejor. ;)
Zenexer
1
Editó su respuesta en octubre de 2013 para incluir mi respuesta que agregué en abril.
Samer Ata
PHP 4:$array_values = array_values($array); $value = $array_values[0];
zdick el
38

PHP 7.3 agregó dos funciones para obtener la primera y la última clave de una matriz directamente sin modificar la matriz original y sin crear ningún objeto temporal:

Además de ser semánticamente significativas, estas funciones ni siquiera mueven el puntero de matriz (como foreach lo haría).

Teniendo las claves, uno puede obtener los valores directamente mediante las claves.


Ejemplos (todos ellos requieren PHP 7.3+)

Obteniendo la primera / última clave y valor:

$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];

Obteniendo el primer / último valor como líneas simples, suponiendo que la matriz no puede estar vacía :

$first_value = $my_array[ array_key_first($my_array) ];

$last_value = $my_array[ array_key_last($my_array) ];

Obteniendo el primer / último valor como líneas simples, con valores predeterminados para matrices vacías:

$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) ];
Alex Shesterov
fuente
Acorte con el operador de fusión nula , por lo general, nulo es el valor predeterminado, por lo que: $first_value = $my_array[array_key_first($my_array)] ?? null;
Mitchell McKenna
29

Suponer:

$array = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

Solo usa:

$array[key($array)]

para obtener el primer elemento o

key($array)

para obtener la primera clave.

O puede desvincular el primero si desea eliminarlo.

Lucas
fuente
99
¿Qué no simplemente usar currententonces?
Marco Demaio
27

Algunas matrices no funcionan con funciones como list, resetocurrent . Tal vez son matrices "falsas", implementando parcialmente ArrayIterator, por ejemplo.

Si desea extraer el primer valor independientemente de la matriz, puede provocar un cortocircuito en un iterador:

foreach($array_with_unknown_keys as $value) break;

Su valor estará disponible en $value y el bucle se romperá después de la primera iteración. Esto es más eficiente que copiar una matriz potencialmente grande a una función como array_unshift (array_values ​​($ arr)).

También puedes tomar la llave de esta manera:

foreach($array_with_unknown_keys as $key=>$value) break;

Si está llamando a esto desde una función, simplemente regrese temprano:

function grab_first($arr) {
    foreach($arr as $value) return $value;
}
Lee Benson
fuente
Supongo que esta es una de las formas más rápidas porque usar el lenguaje construye foreach en lugar de una llamada de función (que es más costosa). designcise.com/web/tutorial/…
Ildar Amankulov
19

De los ayudantes de Laravel :

function head($array)
{
    return reset($array);
}

La matriz que se pasa por valor a la función, reset () afecta el puntero interno de una copia de la matriz y no toca la matriz original (tenga en cuenta que devuelvefalse si la matriz está vacía).

Ejemplo de uso:

$data = ['foo', 'bar', 'baz'];

current($data); // foo
next($data); // bar
head($data); // foo
next($data); // baz

Además, aquí hay una alternativa. Es marginalmente más rápido, pero más interesante. Permite cambiar fácilmente el valor predeterminado si la matriz está vacía:

function head($array, $default = null)
{
    foreach ($array as $item) {
        return $item;
    }
    return $default;
}

Para el registro, aquí hay otra respuesta mía , para el último elemento de la matriz.

Gras Double
fuente
17

¡Mantén esto simple! Aquí hay muchas respuestas correctas, pero para minimizar toda la confusión, estas dos funcionan y reducen muchos gastos generales:

key($array)obtiene la primera clave de una matriz
current($array)obtiene el primer valor de una matriz


EDITAR: con
respecto a los comentarios a continuación. Se mostrará el siguiente ejemplo: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));
tfont
fuente
11
Uhh currentes igual al elemento actual Debe restablecer el puntero al comienzo de la matriz para asegurarse de que realmente esté al principio.
waterloomatt
current () obtendrá el elemento actual, no el primer elemento. Es diferente.
Amirhossein Tarmast
current funcionará si solo hay un elemento en la matriz.
Zameer Fouzan
15

Simplemente haz:

array_shift(array_slice($array,0,1));
DiverseAndRemote.com
fuente
14

Haría echo current($array).

usuario1485518
fuente
1
@hsz No importa, current()no da error cuando se pasan no referencias. Siempre que el puntero todavía esté al principio, esto funciona.
Dan Lugg
pero produce un Aviso que ensucia y registra bien tus registros ... deberías deshacerte de los Avisos que también se tejen si no son críticos
dmikam
1
@dmikam no, no lo hace. En realidad, resetproduce el aviso "Solo las variables deben pasarse por referencia", mientras currentque no: Ejemplo del Editor PHP en línea decurrent(array_filter(...)); .
CPHPython
@CPHPython, parece que tienes razón ... parece que tuve esta idea de la corriente de los viejos tiempos de PHP 4, donde realmente produce un error fatal: sandbox.onlinephpfunctions.com/code/... El único problema que veo al usar la corriente es que no garantiza que el elemento devuelto sea el primer elemento de una matriz (la función llamada puede modificar el puntero interno). Prácticamente puede devolver un elemento aleatorio de una matriz.
dmikam
1
@CPHPython Un ejemplo un poco artificial, pero demuestra bien mis pensamientos: sandbox.onlinephpfunctions.com/code/... solo imagina que recibes tu matriz de alguna función que usa next(), end()o cualquier otra función que modifique el puntero interno de la matriz. En mi ejemplo, current()devuelve nulo porque el puntero interno está "fuera del rango" de la matriz. Pero puede 'virtualmente' apuntar a cualquier elemento / aleatorio también.
dmikam
13
$arr = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
foreach($arr as $first) break;
echo $first;

Salida:

apple
tekin
fuente
10
$myArray = array (4 => 'apple', 7 => 'orange', 13 => 'plum');
$arrayKeys = array_keys($myArray);

// The first element of your array is:
echo $myArray[$arrayKeys[0]];
Jacob Topping
fuente
No fui como se describe en la respuesta aceptada. Usé el tuyo gracias
JayKandari
9
$array=array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

$firstValue = each($array)[1];

Esto es mucho más eficiente que array_values()porque la each()función no copia toda la matriz.

Para obtener más información, consulte http://www.php.net/manual/en/function.each.php

rustyx
fuente
because the each() function does not copy the entire array.+1
2
Pero la cuestión es que debe reiniciar antes, si el puntero interno no está al principio no obtendrá el primer elemento.
Carlos Goce
Pero cada () recibe una matriz por referencia y el requisito de las preguntas iniciales es no hacerlo
dmikam
8

Una forma grosera es:

$foo = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );

function get_first ($foo) {
    foreach ($foo as $k=>$v){
        return $v;
    }
}

print get_first($foo);
William Macdonald
fuente
3
Al menos eres honesto, ¡es grosero! Pero funciona, y lo he usado en el pasado hasta aprender la técnica list () anterior.
random_user_name
1
Si está haciendo esto, podría usarlo reset()ya que el puntero de matriz se reinicia antes de que foreachse llame de todos modos.
Tyzoid
7

Obtén el primer elemento:

array_values($arr)[0]

Obtener el último elemento

array_reverse($arr)[0]
Adobe
fuente
Las claves numéricas se conservan con array_reverse, por lo que aún devolverá el primer elemento. 3v4l.org/2729s
Don't Panic
7

La mayoría de estos trabajos! PERO para una llamada rápida de una sola línea (bajo recurso):

$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)

Aunque esto funciona, y decentemente bien, también vea mi respuesta adicional: https://stackoverflow.com/a/48410351/1804013

tfont
fuente
55
Esto es equivalente a usar current($array), que requiere que el puntero interno de la matriz esté en el primer elemento de todos modos, en cuyo caso, echo reset($array)es el más apropiado.
Tyzoid
@Tyzoid, en realidad escribió otra respuesta aquí con su sugerencia , pero omitió su explicación ... Gracias.
CPHPython
@Tyzoid: Hice una respuesta / actualización adicional hace un tiempo: stackoverflow.com/a/48410351/1804013
tfont
5

Creo que usar array_values sería tu mejor apuesta aquí. Podría devolver el valor en el índice cero del resultado de esa función para obtener 'apple'.

jmking
fuente
5

Esto es un poco tarde para el juego, pero me presentaron un problema en el que mi matriz contenía elementos de matriz como elementos secundarios dentro de ella, y por lo tanto no podía obtener una representación de cadena del primer elemento de matriz. Al usar la current()función de PHP , logré esto:

<?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...
?>

Gracias a todas las soluciones actuales me ayudaron a llegar a esta respuesta, ¡espero que esto ayude a alguien alguna vez!

Chris Kempen
fuente
4

Utilizar:

$first = array_slice($array, 0, 1);  
$val= $first[0];

De manera predeterminada, array_sliceno conserva las claves, por lo que podemos usar cero de forma segura como índice.

Bazi
fuente
4

Dos soluciones para ti.

Solución 1 - Solo usa la llave. No has dicho que no puedes usarlo. :)

<?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. */');
?>

Solución 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. */');
?>

Solución 3 - array_keys ()

echo $array[array_keys($array)[0]];
Jens A. Koch
fuente
2

Esta no es una respuesta tan simple en el mundo real. Supongamos que tenemos estos ejemplos de posibles respuestas que puede encontrar en algunas bibliotecas.

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

Como puede ver, tenemos varias soluciones de 'una línea' que funcionan bien en algunos casos, pero no en todos.

En mi opinión, debe tener ese controlador solo con matrices.

Ahora hablando de rendimiento, suponiendo que siempre tengamos una matriz, como esta:

$elm = empty($array) ? null : ...($array);

...you would use without errors:
$array[count($array)-1];
array_shift
reset
array_values
array_slice

array_shiftes más rápido que reset, es más rápido que [count () - 1], y estos tres son más rápidos que array_valuesy array_slice.

Steven Koch
fuente
2

Me imagino que el autor solo estaba buscando una forma de obtener el primer elemento de una matriz después de obtenerlo de alguna función ( mysql_fetch_row , por ejemplo) sin generar un ESTRICTO "Solo las variables deben pasarse por referencia".

Si es así, casi todas las formas descritas aquí recibirán este mensaje ... y algunas de ellas usan mucha memoria adicional duplicando una matriz (o alguna parte de ella). Una manera fácil de evitarlo es asignar el valor en línea antes de llamar a cualquiera de esas funciones:

$first_item_of_array = current($tmp_arr = mysql_fetch_row(...));
// or
$first_item_of_array = reset($tmp_arr = func_get_my_huge_array());

De esta manera no obtienes el mensaje ESTRICTO en la pantalla, ni en los registros, y no creas matrices adicionales. Funciona con matrices indexadas y asociativas.

dmikam
fuente
1

Me gusta el ejemplo de "lista", pero "lista" solo funciona en el lado izquierdo de una tarea. Si no queremos asignar una variable, nos veríamos obligados a inventar un nombre temporal, que en el mejor de los casos contamina nuestro alcance y en el peor de los casos sobrescribe un valor existente:

list($x) = some_array();
var_dump($x);

Lo anterior sobrescribirá cualquier valor existente de $ x, y la variable $ x se mantendrá mientras este alcance esté activo (el final de esta función / método, o para siempre si estamos en el nivel superior). Esto se puede solucionar usando call_user_func y una función anónima, pero es torpe:

var_dump(call_user_func(function($arr) { list($x) = $arr; return $x; },
                        some_array()));

Si usamos funciones anónimas como esta, podemos salir con reset y array_shift, a pesar de que usan paso por referencia. Esto se debe a que llamar a una función vinculará sus argumentos, y estos argumentos se pueden pasar por referencia:

var_dump(call_user_func(function($arr) { return reset($arr); },
                        array_values(some_array())));

Sin embargo, esto es realmente excesivo, ya que call_user_func realizará esta asignación temporal internamente. Esto nos permite tratar las funciones de paso por referencia como si fueran valores de paso, sin advertencias ni errores:

var_dump(call_user_func('reset', array_values(some_array())));
Warbo
fuente
1

Un pequeño cambio en lo que Sarfraz publicó es:

$array = array(1, 2, 3, 4, 5);
$output = array_slice($array, 0, 1);
print_r ($output);
Jan Detlefsen
fuente
1

No me gusta jugar con el puntero interno de la matriz, pero también es ineficiente construir una segunda matriz con array_keys()o array_values(), por lo que generalmente defino esto:

function array_first(array $f) {
    foreach ($f as $v) {
        return $v;
    }
    throw new Exception('array was empty');
}
Jesse
fuente
1

Prueba esto:

$fruits = array( 4 => 'apple', 7 => 'orange', 13 => 'plum' );
echo reset($fruits)."\n";

Wakar Ahmad Khan
fuente