Mengakses array asosiatif dengan indeks integer di PHP

93

Saya ingin menetapkan nilai array asosiatif menggunakan indeks array pasangan kunci / nilai. Sebagai contoh:

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

Bagaimana ini bisa mencapai ini tanpa menggunakan string kunci?

Marty
sumber

Jawaban:

189

Gunakan array_keys .

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

Semoga ini membantu.

Donovan
sumber
4
Sebagai catatan tambahan, mengapa pengembang PHP membuat cara non-intuitif untuk mengakses array?
Marty
3
@Marty ini tidak ada hubungannya dengan bagaimana pengembang PHP mengimplementasikannya, tetapi lebih dengan kesalahpahaman Anda tentang cara kerja array. Secara teknis di atas masih menggunakan nama asosiatif. Tidak ada korelasi antara kunci indeks numerik dan asosiatif.
Gordon
2
Anda membuat array asosiatif karena apa yang Anda cari lebih penting daripada posisinya dalam array. Saya pikir ini adalah poin yang bagus. Katakanlah Anda memiliki array dengan nama siswa sebagai kunci dan alamat sebagai nilai. Anda dapat menghubungi alamat siswa dengan namanya. Posisi array itu tidak relevan. Dan Anda dapat mengurutkan array berdasarkan name of the student.
Donovan
@Gordon secara teknis itu benar. Tapi programmer memberikan angka, bukan string. Saya pikir ini adalah arti dari without using a key string.
Donovan
2
@Albert Anda memetakan nomor ini ke string kunci yang sesuai. Itu tidak berarti itu array[1] === $array['foo']. Larik masih bisa berisi nilai lain di $array[1]. Perhatikan bahwa saya tidak mengatakan solusi Anda salah. Itu asumsi OP.
Gordon
27

Tidak ada korelasi antara kunci indeks numerik dan asosiatif.

Ketika Anda mengatakan Anda ingin mengatur nilai array asosiatif menggunakan indeks array dari kunci / nilai , maka Anda harus menggunakan kunci yang diberikan, pengaturan $array[1]tidak sama dengan pengaturan$array['foo'] .

Pertimbangkan larik ini

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

Ini akan memberi

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

Foo adalah elemen kedua dalam larik. Itu offsetnya , tapi tidak ada hubungannya dengan indeks 1. Seperti yang Anda lihat, dalam larik di atas, indeks 1 dikaitkan dengan baz. Salah untuk mengasumsikan bahwa hanya karena fookunci asosiatif pertama itu ada hubungannya dengan kunci numerik 1. Sama seperti sometidak berkorelasi dengan 2.

Demikian juga, untuk array campuran seperti yang ditunjukkan di atas, solusi dengan yang array_keysdisarankan di tempat lain di situs ini tidak akan berfungsi, karena

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

akan memberi

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

Jadi, ketika Anda melakukannya, $array[$keys[1]]Anda benar-benar melakukannya $array['foo']. Tetapi jika Anda ingin mengakses nilai asosiatif kedua dalam array itu ( 'some'), Anda tidak dapat melakukannya $array[$keys[2]]karena itu akan mengevaluasi ke $array[1]dan itu baz.

Offset elemen sama sekali tidak terkait dengan kunci atau nilainya

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

benar-benar berarti

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

yang berarti elemen pada offset 0 adalah foo meskipun kuncinya adalah 100. Jika Anda ingin mengekstrak elemen dari larik dengan offset, Anda harus menggunakan

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

Ini akan membuat sebuah array yang hanya menampung elemen di posisi ketiga.

Atau Anda bisa menggunakan ArrayIterator. The ArrayIteratormengimplementasikan sebuah Seekableantarmuka yang memungkinkan Anda mencari untuk posisi tertentu / offset dalam array dan kemudian mengambil bahwa:

$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value
Gordon
sumber
Minor nit: "jika Anda ingin mengakses nilai asosiatif kedua dalam array itu ('some'), Anda tidak dapat melakukan $ array [$ keys [2]] karena itu akan mengevaluasi ke $ array [1] dan itu baz" Secara teknis, itu karena semua kunci, termasuk yang numerik, adalah kunci asosiatif - 4 nilai yang dikembalikan oleh array_keys. Tidak ada entitas seperti "kunci non-asosiatif". Jika Anda bermaksud untuk menunjukkan bahwa Anda tidak dapat mengembalikan kunci string ke-2 (dengan mengasumsikan array kunci hanya berisi string), maka yang Anda katakan adalah benar. $stringKeys = array_filter(array_keys($array), "is_string");memberikan kunci string.
ToolmakerSteve
17

Sementara array_keys()memungkinkan akses ke kunci ke-n, array_valuesakan memberi Anda nilai ke-n.

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

akan menampilkan 'Dua'.

Apakah ada keuntungan yang satu dibandingkan yang lain? Nah, satu-satunya yang kecil yang bisa saya lihat adalah jumlah akses array.

Dengan array_keys()Anda perlu 3.

  1. Dapatkan kunci dari larik data.
  2. Dapatkan kunci ke-n dari daftar kunci.
  3. Dapatkan nilai menggunakan kunci ke-n dari larik data.

Dengan array_values(), Anda hanya perlu 2.

  1. Dapatkan nilai dari larik data.
  2. Dapatkan nilai n dari daftar nilai.

Tapi, di sisi lain, kunci biasanya lebih kecil dan datanya bisa sangat bertumpuk, jadi, jika seimbang, menggunakan array_keys()mungkin lebih aman.

Richard A Quadling
sumber
3

Jika arraynya besar, keduanya array_keysdan array_valuesakan sia-sia karena mereka akan mengalokasikan array baru dengan ukuran yang sama dengan aslinya, hanya untuk mendapatkan kunci ke - n (atau nilai).

array_slicemenerima offset integer dan bekerja pada array asosiatif. Anda dapat menggunakannya untuk mendapatkan (dan menyetel) kunci ke - n dalam waktu yang konstan.

// 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
sumber
2
Solusi bagus di sini!
Daan
1

Coba ini. Ini bekerja untuk Anda.

$result= array_values($my_arr); // Array with indexes you need
Murali krishna
sumber
1
Harap berhati-hati saat memposting ke utas lama yang sudah memiliki beberapa tanggapan dan jawaban yang diterima. Anda perlu menjelaskan mengapa jawaban baru Anda lebih baik daripada jawaban yang sudah ada.
APC
0

Kemungkinan lain adalah mengubahnya menjadi array normal:

$ arraybuff = implode ("~~~", $ my_arr);
$ my_arr = meledak ("~~~", $ arraybuff);

Di mana "~~~" adalah pemisah yang tidak akan terjadi dalam data Anda.

Sekarang Anda dapat mengakses array menggunakan indeks numerik yang sama dengan offset.

Jika Anda masih perlu mempertahankan array asosiatif Anda, tetapkan saja ke variabel yang berbeda.

kreditor
sumber
Karena Anda harus selalu dan selalu mempertimbangkan, pembatas yang tepat ini dapat terjadi di data Anda, ide ini hanya berfungsi di 99.9999999%. Ada beberapa solusi yang akan bekerja 100%. Selain itu, ini mengatur prosesor untuk banyak pekerjaan dan memori yang terbuang hanya untuk akses array sederhana.
user426486