Ilişkilendirilebilir dizinin ortasında bir dizi değeri nasıl eklenir?

10 Cevap php

Ben bu dizi var diyelim:

$array = array('a'=>1,'z'=>2,'d'=>4);

Daha sonra komut, ben 'z' önce değerini 'c'=>3 eklemek istiyorum. Bunu nasıl yapabilirim?

EDIT: Evet, sırası önemlidir. Ben dizi ile foreach () çalıştırdığınızda, ben bu yeni katma değer dizinin sonuna eklenen istemediğin. Ben Mysql_Fetch_Assoc bu diziyi alıyorum () am

EDIT 2: Yukarıda kullanılan tuşlar yer tutucular vardır. Ksort Kullanma () ne istediğinizi elde değil.

EDIT 3: http://www.php.net/manual/en/function.array-splice.php#88896 ben arıyorum ne yapar ama basit bir şey arıyorum.

EDIT 4: downvotes için teşekkürler. Ben senin cevaplara geri verdi ve tutamadı, böylece downvoted ve cevabını bilmiyordu çünkü soru kapatmak istedi. Teşekkürler.

EDIT 5: yaklaşık 30 sütunlu bir örnek db tablo atın. Ben mysql_fetch_assoc kullanarak bu verileri almak (). Bu yeni dizide, sütununda 'pizza' ve 'içki' sonra, 'pizza' değerleri ve 'içki' birleştiren yeni bir sütun 'full_dinner' eklemek istiyorum böylece ben bahsedilen dizinin bir foreach () çalıştırdığınızda , 'full_dinner' içki 'sonra doğrudan gelir

10 Cevap

Bu basit bir yaklaşım gitmek gibi yeni bir inşa, orijinal dizi yineleme için:

function InsertBeforeKey( $originalArray, $originalKey, $insertKey, $insertValue ) {

    $newArray = array();
    $inserted = false;

    foreach( $originalArray as $key => $value ) {

        if( !$inserted && $key === $originalKey ) {
            $newArray[ $insertKey ] = $insertValue;
            $inserted = true;
        }

        $newArray[ $key ] = $value;

    }

    return $newArray;

}

Sonra sadece çağrı

$array = InsertBeforeKey( $array, 'd', 'c', 3 );

Ben bir şey eksik?

$key = 'z';
$offset = array_search($key, array_keys($array));

$result = array_merge
        (
            array_slice($array, 0, $offset),
            array('c' => 3),
            array_slice($array, $offset, null)
        );

($data Varsayılan ekleme) Varolmayan tuşları Taşıma:

function insertBeforeKey($array, $key, $data = null)
{
    if (($offset = array_search($key, array_keys($array))) === false) // if the key doesn't exist
    {
        $offset = 0; // should we prepend $array with $data?
        $offset = count($array); // or should we append $array with $data? lets pick this one...
    }

    return array_merge(array_slice($array, 0, $offset), (array) $data, array_slice($array, $offset));
}

Demo:

$array = array('a' => 1, 'z' => 2, 'd' => 4);

// array(4) { ["a"]=> int(1) ["c"]=> int(3) ["z"]=> int(2) ["d"]=> int(4) }
var_dump(insertBeforeKey($array, 'z', array('c' => 3)));

// array(4) { ["a"]=> int(1) ["z"]=> int(2) ["d"]=> int(4) ["c"]=> int(3) }
var_dump(insertBeforeKey($array, 'y', array('c' => 3)));

Orijinal soruya göre bulabilirim iyi cevap şudur:

$a = array('a'=>1,'z'=>2,'d'=>4);

$splitIndex = array_search('z', array_keys($a));
$b = array_merge(
        array_slice($a, 0, $splitIndex), 
        array('c' => 3), 
        array_slice($a, $splitIndex)
);

var_dump($b);
array(4) {
  ["a"]=>
  int(1)
  ["c"]=>
  int(3)
  ["z"]=>
  int(2)
  ["d"]=>
  int(4)
}

Lütfen diziler bu çözümü veya başka kullanmak eğer olursa olsun, dahili bellekte oldukça bazı verileri çoğaltmak olacak ne kadar büyük bağlı.

Ayrıca beşinci düzenleme alternatif SQL sorgu gelişmiş olabileceğini gösteriyor gibi görünüyor. Orada ne yapmak istiyor gibi görünüyor böyle bir şey olacaktır:

SELECT a, b, CONCAT(a, ' ', b) AS ab FROM ... WHERE ...

Lütfen SELECT ifadeyi değiştirerek PHP çözüm gereksiz hale olsaydı, kesinlikle değiştirilmiş SQL ile gitmeli.

function insertValue($oldArray, $newKey, $newValue, $followingKey) {

    $newArray = array ();
    foreach (array_keys($oldArray) as $k) {
        if ($k == $followingKey)
            $newArray[$newKey] = $newValue;
        $newArray[$k] = $oldArray [$k];
    }

    return $newArray;
}

Sen olarak diyoruz

insertValue($array, 'c', '3', 'z')

As for Edit 5:

okur, böylece sql düzenlemek

SELECT ..., pizza, drink, pizza+drink as full_meal, ... FROM ....

ve otomatik olarak sütun var:

Array (
  ...
  'pizza' => 12,
  'drink' => 5,
  'full_meal' => 17,
  ...
)

Ilişkilendirilebilir diziler sipariş edilmez, böylece sadece $array['c'] = 3 ile ekleyebilirsiniz.

Sırası önemli ise, bir seçenek daha fazla gibi bir veri yapısına geçmek edilir:

$array = array(
   array('a' => 1),
   array('b' => 2)
   array('d' => 4)
);

Ardından, array_splice($array, 2, 0, array('c' => 3)) 2 konumundaki eklemek için kullanın. Üzerine kılavuzuna bakın array_splice.

Alternatif bir yaklaşım anahtarları iteratif sırasını belirleyen bir sipariş endeksi ile ilişkisel dizi yapısını takviye etmektir. Örneğin:

$index = array('a','b','d');

// Add new value and update index
$array['c'] = 3;
array_splice($index, 2, 0, 'c');

// Iterate the array in order
foreach $index as $key {
   $value = $array[$key];
}

Tuşu ile bir kabarcık-sıralama yaparken kendi sortmap tanımlayabilirsiniz. Muhtemelen korkunç verimli değil ama çalışıyor.

<pre>
<?php

$array = array('a'=>1,'z'=>2,'d'=>4);

$array['c'] = 3;

print_r( $array );

uksort( $array, 'sorter' );

print_r( $array );

function sorter( $a, $b )
{
    static $ordinality = array(
        'a' => 1
      , 'c' => 2
      , 'z' => 3
      , 'd' => 4
    );
    return $ordinality[$a] - $ordinality[$b];
}

?>
</pre>

İşte bu aynı kavramı kullanarak DiziNesnesi dayalı bir yaklaşım

$array = new CitizenArray( array('a'=>1,'z'=>2,'d'=>4) );
$array['c'] = 3;

foreach ( $array as $key => $value )
{
    echo "$key: $value <br>";
}

class CitizenArray extends ArrayObject
{
    static protected $ordinality = array(
        'a' => 1
      , 'c' => 2
      , 'z' => 3
      , 'd' => 4
    );

    function offsetSet( $key, $value )
    {
        parent::offsetSet( $key, $value );
        $this->uksort( array( $this, 'sorter' ) );
    }

    function sorter( $a, $b )
    {
        return self::$ordinality[$a] - self::$ordinality[$b];
    }
}

Şu an için ben yeni dizilerin oluşumunu minimize denemek için bulunan en iyi bu iki işlevi vardır:

İlki orijinal diziye değerini değiştirmek için denemek ve ikinci bir yeni bir dizi döndürür.

// replace value into the original array
function insert_key_before_inplace(&$base, $beforeKey, $newKey, $value) {
 $index = 0;
 foreach($base as $key => $val) {
    if ($key==$beforeKey) break;
    $index++;
 }
 $end = array_splice($base, $index, count($base)-$index);
 $base[$newKey] = $value;
 foreach($end as $key => $val) $base[$key] = $val;
}


$array = array('a'=>1,'z'=>2,'d'=>4);

insert_key_before_inplace($array, 'z', 'c', 3);

var_export($array); // array ( 'a' => 1, 'c' => 3, 'z' => 2, 'd' => 4, )

// create new array
function insert_key_before($base, $beforeKey, $newKey, $value) {
 $index = 0;
 foreach($base as $key => $val) {
    if ($key==$beforeKey) break;
    $index++;
 }
 $end = array_splice($base, $index, count($base)-$index);
 $base[$newKey] = $value;
 return $base+$end;
}


$array = array('a'=>1,'z'=>2,'d'=>4);

$newArray=insert_key_before($array, 'z', 'c', 3);

var_export($array); // ( 'a' => 1, 'z' => 2, 'd' => 4, )

var_export($newArray); // array ( 'a' => 1, 'c' => 3, 'z' => 2, 'd' => 4, )

Bu deneyin

$array['c']=3;

Bir ilişkisel dizi varsayılan olarak sipariş değil, ancak bunları sıralamak istedim alfabetik bunu anahtar ile diziyi sıralamak için ksort() kullanabilirsiniz.

Eğer ksort(), olur se için PHP article kontrol ederseniz örneğin kendi anahtarı tarafından bir dizi sıralamak kolay:

<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
    echo "$key = $val\n";
}
?>

// The above example will output:
a = orange
b = banana
c = apple
d = lemon

Eğer yaparak ekleyebilirsiniz

$array['c']=3;

kesinlikle bu baskı amaçlı kriteri istiyorsanız ve PHP'nin ksort ($ dizi) işlevini kullanabilirsiniz

tuşları ksort sıralanabilir değilseniz, o zaman php uasort işlevini kullanarak kendi sıralama oluşturmak zorunda olacak. Burada örneklere bakın

http://php.net/manual/en/function.uasort.php