Accéder à un tableau associatif par index entier en PHP

92

Je souhaite définir la valeur d'un tableau associatif à l'aide de l'index de tableau de la paire clé / valeur. Par exemple:

$my_arr = array( "bling" => "some bling", "bling2" => "lots O bling" );
$my_arr[1] = "not so much bling";  // Would change the value with key bling2.

Comment cela peut-il être accompli sans utiliser la chaîne de clé?

Marty
la source

Réponses:

188

Utilisez array_keys .

$keys = array_keys($my_arr);
$my_arr[$keys[1]] = "not so much bling";

J'espère que cela t'aides.

Donovan
la source
4
En passant, pourquoi les développeurs PHP créeraient-ils un moyen aussi peu intuitif d'accéder à un tableau?
Marty
3
@Marty, cela a moins à voir avec la façon dont les développeurs PHP l'ont implémenté, mais plus avec votre incompréhension du fonctionnement des tableaux. Techniquement, ce qui précède utilise toujours le nom associatif. Il n'y a pas de corrélation entre les clés d'index numériques et associatives.
Gordon
2
Vous créez un tableau associatif car ce que vous recherchez est plus important que sa position dans le tableau. Je pense que c'est un bon point. Supposons que vous ayez un tableau avec les noms des étudiants comme clés et les adresses comme valeurs. Vous pouvez accéder à l'adresse d'un étudiant par son nom. La position du tableau n'a pas d'importance. Et vous pouvez trier le tableau par name of the student.
Donovan
@Gordon techniquement c'est vrai. Mais le programmeur fournit un nombre, pas une chaîne. Je pense que c'est le sens de without using a key string.
Donovan
2
@Albert vous mappez ce numéro à la chaîne de clé appropriée. Cela ne veut pas dire que array[1] === $array['foo']cependant. Le tableau peut encore contenir une autre valeur à $array[1]. Notez que je ne dis pas que votre solution est fausse. C'est l'hypothèse du PO.
Gordon
27

Il n'y a pas de corrélation entre les clés d'index numériques et associatives.

Lorsque vous dites que vous souhaitez définir la valeur d'un tableau associatif à l'aide de l'index du tableau de la clé / valeur , vous devez utiliser la clé donnée, le paramètre $array[1]n'est pas le même que le paramètre $array['foo'].

Considérez ce tableau

print_r( array('foo', 'foo' => 'bar', 'baz', 'some' => 'value') );

Cela donnera

Array
(
    [0] => foo
    [foo] => bar
    [1] => baz
    [some] => value
)

Le toto est le deuxième élément du tableau. C'est le décalage , mais cela n'a rien à voir avec l'index 1. Comme vous pouvez le voir, dans ce tableau ci-dessus, l'index 1 est associé à baz. Il est faux de supposer que, simplement parce que fooc'est la première clé associative, cela a quelque chose à voir avec la clé numérique réelle 1. Tout comme somene correspond pas à 2.

De même, pour un tableau mixte comme indiqué ci-dessus, la solution array_keyssuggérée ailleurs sur ce site ne fonctionnera pas, car

print_r( array_keys(array('foo', 'foo' => 'bar', 'baz', 'some' => 'value')) );

va donner

Array
(
    [0] => 0
    [1] => foo
    [2] => 1
    [3] => some
)

Alors, quand vous faites, $array[$keys[1]]vous faites vraiment $array['foo']. Mais si vous vouliez accéder à la deuxième valeur associative dans ce tableau ( 'some'), vous ne pouvez pas le faire $array[$keys[2]]car cela serait évalué à $array[1]et c'est baz.

Le décalage d'un élément n'a aucun rapport avec sa clé ou sa valeur

print_r(
    array(
        100    => 'foo',
        'foo'  => 'bar',
        50     => 'baz',
        'some' => 'value'
    )
);

signifie vraiment

Array
( //key       value     offset/position
    [100]  => foo       // 0
    [foo]  => bar       // 1
    [50]   => baz       // 2
    [some] => value     // 3
)

ce qui signifie que l'élément à l'offset 0 est foo bien que sa clé soit 100. Si vous voulez extraire des éléments d'un tableau par offset, vous devez utiliser

$third = array_splice($array, 2, 1);
echo $third[0]; // baz

Cela créerait un tableau contenant uniquement l'élément à la troisième position.

Ou vous pouvez utiliser un fichier ArrayIterator. Il ArrayIteratorimplémente une Seekableinterface qui vous permet de rechercher une position / un décalage spécifique dans le tableau, puis de récupérer cela:

$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value
Gordon
la source
Minor nit: "si vous vouliez accéder à la deuxième valeur associative dans ce tableau ('some'), vous ne pouvez pas faire $ array [$ keys [2]] car cela donnerait la valeur $ array [1] et c'est baz" Techniquement, c'est parce que toutes les clés, y compris les clés numériques, sont des clés associatives - les 4 valeurs renvoyées par array_keys. Il n'existe pas d'entité telle qu'une "clé non associative". Si vous vouliez souligner que vous ne pouvez pas renvoyer la 2ème clé de chaîne (en supposant que le tableau de clés ne contient que des chaînes), alors ce que vous dites est correct. $stringKeys = array_filter(array_keys($array), "is_string");donne des clés de chaîne.
ToolmakerSteve
17

Tandis que array_keys()permet l'accès à la nième clé, array_valuesvous donnera la nième valeur.

<?php
$array = [
   0     => 'Zero',
   '1'   => 'One',
   'Two' => 'Two',
];
echo array_values($array)[2];
?>

affichera «Deux».

Y a-t-il un avantage de l'un sur l'autre? Eh bien, le seul mineur que je peux voir est le nombre d'accès au tableau.

Avec array_keys()vous devez 3.

  1. Récupérez les clés du tableau de données.
  2. Récupérez la nième clé dans la liste des clés.
  3. Obtenez la valeur à l'aide de la nième clé du tableau de données.

Avec array_values(), vous n'avez besoin que de 2.

  1. Récupérez les valeurs du tableau de données.
  2. Obtenez la nième valeur de la liste de valeurs.

Mais, d'un autre côté, les clés sont normalement plus petites et les données peuvent être extrêmement imbriquées, donc, dans l'ensemble, l'utilisation de array_keys()est probablement plus sûre.

Richard A Quadling
la source
3

Si le tableau est grand, les deux array_keyset array_valuesseront inutiles car ils alloueront un nouveau tableau de la même taille que l'original, juste pour obtenir la nième clé (ou valeur).

array_sliceaccepte un offset entier et fonctionne sur des tableaux associatifs. Vous pouvez l'utiliser pour obtenir (et définir) la nième clé en temps constant.

// This will at most allocate 2 temporary arrays of 1 element each
$key = array_keys(array_slice($array, $n, 1, true))[0];

$array[$key] = $value;
Jesse
la source
2
Belle solution ici!
Daan
1

Essaye ça. Cela fonctionne pour vous.

$result= array_values($my_arr); // Array with indexes you need
Murali Krishna
la source
1
Soyez prudent lorsque vous publiez sur un ancien fil de discussion qui a déjà plusieurs réponses et une réponse acceptée. Vous devez expliquer pourquoi votre nouvelle réponse est meilleure que celle existante.
APC
0

Une autre possibilité est de le convertir en un tableau normal:

$ arraybuff = imploser ("~~~", $ mon_arr);
$ my_arr = exploser ("~~~", $ arraybuff);

Où "~~~" est un délimiteur qui n'apparaîtra pas dans vos données.

Vous pouvez maintenant accéder au tableau en utilisant des index numériques égaux aux décalages.

Si vous avez encore besoin de conserver votre tableau associatif, affectez-le simplement à une variable différente.

rédacteur
la source
Étant donné que vous devez toujours et toujours considérer que ce délimiteur exact peut apparaître dans vos données, cette idée ne fonctionne que dans 99,9999999%. Il existe plusieurs solutions qui fonctionneront à 100% .En outre, cela met le processeur à beaucoup de travail et de mémoire gaspillée pour un simple accès au tableau.
user426486