11 Kasım 2008

Doğrusal diziyi ağaç yapısına dönüştürme

Php gibi sunucu taraflı dillerin ilk ortaya çıkan kullanım alanları muhtemelen form verilerini işlemektir. Bunlara iletişim formları ve çeşitli kayıt formlarını örnek verebiliriz. Ancak formların kullanımı bunlarla sınırlı değildir. Karmaşık veri yapılarını oluşturmak üzere kullanıcıdan giriş kabul etmek amacıyla da form girişi istenebilir. Böyle durumlarda karşılaşabileceğiniz bir sorun doğrusal bir dizi olarak elde ettiğiniz veriyi ($_POST, $_GET, $_REQUEST dizileri) kullanmak için önce bu diziyi yapısal bir halde sınıflandırmaktır. Özellikle kullanıcının giriş yapacağı formda javascript ile yeni alanlar eklemesine izin verecekseniz bu dizi daha da uzun ve karmaşık bir hal alacaktır. Bu sorunla başa çıkmayı kolaylaştırmak üzere bir işlev yazmaya karar verdim:
[php]
function array2tree($arr,$seperator='->')
{
$arr2 = array();
foreach($arr as $key=>$value){
$root = &$arr2;
$levels = explode($seperator,$key);
$n = count($levels);
$i = 0; foreach($levels as $level){
$i++;
if( !isset($root[$level])){ //seviye daha önceden tanımlı değilse
if($i==$n)//hedef seviye ise değeri aktar
$root[$level]=$value;
else //hedef seviye değilse dizi olarak tanımla
$root[$level]=array();
}
$root = &$root[$level];
}}
return $arr2;
}
[/php]
Bu işlev, adından da tahmin edeceğiniz gibi doğrusal olarak verilen bir diziyi yapısal bir dizi halinde dönüyor. Ancak bu işlevi kullanmak için dizinizdeki elemanların sayısal değil ilişkisel indisli (associative array) olması gerekiyor. Eğer bu işlevi giriş paragrafında açıkladığım örnekteki gibi form verisi üzerinde kullanacaksanız zaten bu koşulu sağlamış olursunuz. Bu durumda dizimizin anahtar değerleri formdaki name değerleri olacaktır. Örnek olarak aşağıdaki şekilde bir $_POST verimiz olduğunu varsayalım.
[php]
$_POST = array(
"type"=>"list",
"children->child1->name"=>"eleman 1",
"children->child1->value"=>12,
"children->child2->name"=>"eleman 2",
"children->child2->value"=>56
);
[/php]
Anahtar değerlerine yani form elemanlarının isimlerine dikkat edin. İsimlendirme yapılırken bazı elemanlarda -> ayracının kullanıldığını görürsünüz. Şimdi bu dizi üzerinde array2tree işlevini çalıştıralım ve sonucu print_r işlevi ile gösterelim:
print_r( array2tree( $_POST ) );

Bu çağrıyı yaptığınızda aşağıdaki sonucu elde edersiniz. İsimleri -> ayracı ile ayrılan elemanların alt öğeler haline geldiğini görüyorsunuz. children->child2->value elemanı children dizisi içindeki child2 dizisinin value elemanına dönüşmüştür. İşlevde varsayılan ayraç olarak -> kullanıldı ancak ikinci parametreyi kullanarak istediğiniz ayracı kullanabilirsiniz.
Array(   [type] => list   [children] => Array   (       [child1] => Array           (               [name] => eleman 1               [value] => 12           )       [child2] => Array           (               [name] => eleman 2               [value] => 56           )   ))

Hiç yorum yok:

Kripto paralar hakkında

Kripto paralar, merkezi olmayan, şifrelenmiş ve dağıtılmış bir veritabanı olan blok zinciri teknolojisi kullanılarak oluşturulan dijital par...