PHP'de tamsayı indeksine göre ilişkilendirilebilir bir diziye erişim


93

Anahtar / değer çiftinin dizi dizinini kullanarak ilişkilendirilebilir bir dizinin değerini ayarlamak istiyorum. Örneğin:

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

Bu, anahtar dizesini kullanmadan bunu nasıl başarabilir?

Yanıtlar:


189

Array_keys kullanın .

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

Bu yardımcı olur umarım.


4
Bir yan not olarak, PHP geliştiricileri bir diziye erişmek için neden bu kadar sezgisel olmayan bir yol yaratsın?
Marty

3
@Marty bunun PHP geliştiricilerinin onu nasıl uyguladığıyla daha az ilgisi var, ancak dizilerin nasıl çalıştığını yanlış anlamanızla daha çok ilgisi var. Teknik olarak, yukarıdakiler hala ilişkisel adı kullanıyor. Sayısal ve ilişkili dizin anahtarları arasında bir ilişki yoktur.
Gordon

2
İlişkilendirilebilir bir dizi yaratırsınız çünkü aradığınız şey, dizideki konumundan daha önemlidir. Bunun iyi bir nokta olduğunu düşünüyorum. Anahtar olarak öğrenci adlarının ve değer olarak adreslerin olduğu bir diziniz olduğunu varsayalım. Bir öğrencinin adresine isminden ulaşabilirsiniz. Dizinin konumu önemli değil. Ve diziyi buna göre sıralayabilirsiniz name of the student.
Donovan

@Gordon teknik olarak doğru. Ancak programcı bir dizi değil, bir sayı sağlıyor. Sanırım anlamı bu without using a key string.
Donovan

2
@Albert bu sayıyı uygun anahtar dizesine eşliyorsunuz. Bu o anlama gelmez array[1] === $array['foo']. Dizi yine de başka bir değer içerebilir $array[1]. Çözümünüzün yanlış olduğunu söylemediğimi unutmayın. OP'nin varsayımı.
Gordon

27

Sayısal ve ilişkili dizin anahtarları arasında bir ilişki yoktur.

Bir ilişkisel dizinin değerini anahtar / değerin dizi indeksini kullanarak ayarlamak istediğinizi söylediğinizde , verilen anahtarı kullanmanız gerekir, ayar ayar $array[1]ile aynı değildir $array['foo'].

Bu diziyi düşünün

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

Bu verecek

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

Foo, dizideki ikinci öğedir. Bu uzaklıktır , ancak indeks 1 ile ilgisi yoktur. Gördüğünüz gibi yukarıdaki dizide indeks 1 ile ilişkilendirilmiştir baz. Sırf fooilk ilişkili anahtar olduğu için gerçek sayısal anahtar 1 ile bir ilgisi olduğunu varsaymak yanlıştır . Tıpkı some2 ile ilişkili olmadığı gibi .

Benzer şekilde, yukarıda gösterildiği gibi karma bir dizi için array_keys, bu sitede başka bir yerde önerilen çözüm işe yaramayacaktır çünkü

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

verecek

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

Yani yaptığın zaman $array[$keys[1]]gerçekten yapıyorsun $array['foo']. Ancak, bu dizideki ( 'some') ikinci ilişkilendirilebilir değere erişmek istiyorsanız, bunu yapamazsınız $array[$keys[2]]çünkü bu, şeklinde değerlendirilir $array[1]ve bu baz.

Bir öğenin Ofseti, anahtar veya değeriyle tamamen ilgisizdir

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

gerçekten anlamı

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

bu, anahtar 100 olmasına rağmen 0 uzaklığındaki elemanın foo olduğu anlamına gelir. Bir diziden ötelemeye göre eleman çıkarmak istiyorsanız, kullanmanız gerekir

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

Bu, yalnızca üçüncü pozisyondaki elemanı tutan bir dizi oluşturacaktır.

Veya bir ArrayIterator. ArrayIteratorUygular bir Seekablebelirli bir konuma etmeye olanak arayüz / dizide ofset ve daha sonra bu getirme:

$iterator = new ArrayIterator($array);
$iterator->seek(3);
echo $iterator->current(); // value

Minor nit: "Eğer bu dizideki ikinci ilişkilendirilebilir değere ('bazı') erişmek isterseniz, $ array [$ keys [2]] yapamazsınız çünkü bu $ array [1] olarak değerlendirilir ve bu baz" Teknik olarak, bunun nedeni , sayısal olanlar da dahil olmak üzere tüm anahtarların ilişkilendirilebilir anahtarlar olmasıdır - tarafından döndürülen 4 değer array_keys. "İlişkili olmayan anahtar" diye bir varlık yoktur. 2. dize anahtarını döndüremeyeceğinizi belirtmek istediyseniz (anahtar dizisinin yalnızca dizeleri içerdiğini varsayarak), o zaman söyledikleriniz doğrudur. $stringKeys = array_filter(array_keys($array), "is_string");dize anahtarları verir.
ToolmakerSteve

17

array_keys()N'inci anahtara erişime izin verirken , array_valuessize n'inci değeri verecektir.

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

'İki' çıktı verir.

Birinin diğerine göre avantajı var mı? Eh, görebildiğim tek küçük şey, dizi erişimlerinin sayısı.

İle array_keys()3 olarak gerek.

  1. Veri dizisinden anahtarları alın.
  2. Anahtar listesinden n'inci anahtarı alın.
  3. Veri dizisindeki n'inci anahtarı kullanarak değeri alın.

İle array_values()sadece 2'ye ihtiyacınız var.

  1. Veri dizisinden değerleri alın.
  2. Değerler listesinden n'inci değeri alın.

Ancak, diğer yandan, anahtarlar normalde daha küçüktür ve veriler büyük ölçüde iç içe olabilir, bu nedenle dengede, kullanmak array_keys()muhtemelen daha güvenlidir.


3

Dizi büyükse, hem Eğer array_keysve array_valuesonlar sadece almak için, orijinal olarak yeni bir dizi aynı boyutta tahsis edecek beri savurgan olacak n'inci anahtarı (veya değeri).

array_slicebir tamsayı uzaklığını kabul eder ve ilişkilendirilebilir diziler üzerinde çalışır. Sabit zamanda n'inci anahtarı elde etmek (ve ayarlamak) için kullanabilirsiniz .

// 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;

2
Burada güzel çözüm!
Daan

1

Bunu dene. Senin için çalışıyor.

$result= array_values($my_arr); // Array with indexes you need

1
Zaten birkaç yanıtı ve kabul edilmiş bir yanıtı olan eski bir ileti dizisine gönderi gönderirken lütfen dikkatli olun. Yeni cevabınızın neden mevcut cevaplardan daha iyi olduğunu açıklamanız gerekiyor.
APC

0

Başka bir olasılık da onu normal bir diziye dönüştürmektir:

$ arraybuff = implode ("~~~", $ my_arr);
$ my_arr = patlat ("~~~", $ dizibuff);

"~~~", verilerinizde bulunmayacak bir sınırlayıcıdır.

Artık diziye uzaklıklara eşit sayısal indeksler kullanarak erişebilirsiniz.

İlişkili dizinizi hala korumanız gerekiyorsa, onu farklı bir değişkene atamanız yeterlidir.


Her zaman ve her zaman düşünmeniz gerektiğinden, bu kesin sınırlayıcı verilerinizde bulunabilir, bu fikir sadece% 99,9999999 oranında çalışır. % 100 çalışacak birkaç çözüm vardır. Ayrıca, bu işlemciyi sadece basit bir dizi erişimi için çok fazla çalışmaya ve boşa harcanan belleğe ayarlar.
user426486
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.