SimpleXML nesneleri bir dizi sıralama

6 Cevap php

Ben Stackoverflow üzerinde ne buldum okudum ve bu hala belirsiz duyuyorum ettik.

Ben SimpleXML böyle bir şey nesneleri bir dizi var:

array(2) {
  [0]=>
  object(SimpleXMLElement)#2 (2) {
    ["name"]=>
    string(15) "Andrew"
    ["age"]=>
    string(2) "21"
  }
  [1]=>
  object(SimpleXMLElement)#3 (2) {
    ["name"]=>
    string(12) "Beth"
    ["age"]=>
    string(2) "56"
  }
}

Ve ben artan veya azalan, ne olursa olsun sütuna göre sıralamak mümkün olmak istiyorum. Gibi bir şey:

sort($data, 'name', 'asc');

Ben nesneleri yukarıdaki dizide geçmek ve ben beğendim hangisi anahtarının değerine göre sıralama nerede.

. Başvuru için, benzer bir NET çözüm bu doğrultuda olacaktır:

XmlSortOrder order = XmlSortOrder.Ascending;
    if ( sortDirection == "asc" ) {
        order = XmlSortOrder.Ascending;
    }
    expression.AddSort( columnSortingOn + "/text()", order, 
        XmlCaseOrder.UpperFirst, "en-us", XmlDataType.Text ); 

İnsanların ne gördüm

"Usort kullanın"

PHP kılavuzda temel bir örnek izledi ama bu gerçekten açıklamak değil. En azından benim için. Ben de insanların SimpleDOM gibi harici bir kütüphaneyi kullanarak öneririz ama küçük bir şey (ben henüz çözemez ama, görünüşte) Bunun için harici bir şey kullanarak kaçınmak istiyorsanız gördüm.

Herhangi bir Yardım takdir, teşekkür ederiz!

6 Cevap

Ben kullanmak için öne insanlar SimpleDOM Bana olurdu sanırım. :)

Ben SimpleDOM yazdım :: sort () tam olarak bu durum için, bir tahkim ifade (ya da keyfi ifadeler) tarafından SimpleXMLElement sıralamak için sıkıcı ve won olan array_multisort() kullanmak gerekir, çünkü 't size yararlı bir şey öğretmek.

Önce her SimpleXMLElement karşılık anahtar => değer çiftleri bir vekil dizi ve onlar sıralanır olacak olan değeri oluşturun: Burada çalıştığını nasıl kısa versiyonu bulunuyor. Eğer <age/> bunları sıralamak istiyorsanız örnekte, dizi olurdu array(21, 56). Sonra sorting modifiers gibi SORT_DESC veya SORT_NUMERIC sonra nihayet sıralamak istediğiniz dizi, geçilecek olan gibi herhangi bir sayıyla ilk argüman olarak "vekil dizi" ile array_multisort() çağrı referans ile bu.

Böyle bir şey ile sona erecek:

$nodes = array(
    new SimpleXMLElement('<person><name>Andrew</name><age>21</age></person>'),
    new SimpleXMLElement('<person><name>Beth</name><age>56</age></person>')
);

function xsort(&$nodes, $child_name, $order = SORT_ASC)
{
    $sort_proxy = array();

    foreach ($nodes as $k => $node)
    {
        $sort_proxy[$k] = (string) $node->$child_name;
    }

    array_multisort($sort_proxy, $order, $nodes);
}

xsort($nodes, 'name', SORT_ASC);
print_r($nodes);

xsort($nodes, 'age', SORT_DESC);
print_r($nodes);

Ama gerçekten, bunun yerine daha kod ile kendinizi yormadan size korumak gerekir ve muhtemelen userspace array_multisort() yeniden biten, varolan çözümleri kaldıraç gerekir. Böyle bir sıralama algoritması / rutin ilginç bir şey yok, zaman daha iyi zaten mevcut olmayan bir şey üzerinde harcanan olurdu.

usort function PHP anlatmak sizin için sağlar

Hey, sen! Sıralama bu dizi ben yazdım bu işlev size veriyorum.

Bu SimpleXML ile yapmak için özel bir şey vardır. Bu yerleşik dizi veri toplama PHP sıralamak için genel bir fonksiyon bulunuyor.

Sen diziyi sıralamak için bir fonksiyon, örnek yöntemi veya statik yöntem yazmak gerekir. Usort için ikinci argüman hangi fonksiyonu, örnek yöntemini, ya da statik yöntemini belirlemenize olanak tanır bir sözde-türü olan bir PHP Callback kabul eder.

Yazdığınız fonksiyonu iki argüman kabul eder. Bunlar dizisi iki farklı değerleri olacak

function cmp($a, $b)
{
            if ($a == $b) {
                return 0;
            }
            if($a < $b) {
                return -1;
            }
            if($a > $b) {
                return 1;
            }
}

Üç değerden birini döndürmek için bu işlevi yazmak gerekir.

If $a == $b, return 0
If $a > $b, return -1
if $a > $v, return 1  

Eğer usort aradığınızda, PHP sizin örnekte, $ a., Bu durumda cmp tekrar ve tekrar dizi sıralanır kadar (sıralama işlevi / yöntemini çağırarak, sizin dizi boyunca çalışacak ve $ b olacak SimpleXML nesneleri.

Ben zaten beni yenmek fark kadar usort() tavsiye hazırdı. Kod örnekleri geçmişte çok iyi yapmadım, ben sadece düz İngilizce olarak anlatmaya çalışacağım ve umarım size doğru yönde işaret alırsınız.

Ile usort(), kendi kullanıcı oluşturulan "algoritma" yaratmak. usort() fonksiyonu nesnelerden her birine başka nasıl ilişkili belirlemek için kendi karşılaştırma işlevini çağırır. Karşılaştırma fonksiyonu yazarken, sizin dizideki iki nesne geçti alacak. Bu iki nesne ile, aslında usort() birinci nesne LESS THAN, EQUAL TO, ya da GREATER THAN ikinci olup olmadığını söyleyen bir sonuca dönmek nesnesi. Sen (sırasıyla) -1, 0 veya 1 dönen bunu. İşte bu. Sadece iki nesne birbirine karşılaştırmak ve gerçek sıralama mekaniği Sizin için usort() tarafından nasıl ele dert var.

Tamam, şimdi bir yarı-pratik bir örnek için:

function myCompare($obj1, $obj2) {
    if($obj1->someInt == $obj2->someInt) {
        return 0; // equal to
    } else if($obj1->someInt < $obj2->someInt) {
        return -1; // less than
    } else {
        return 1; // greater than
    }
}

$myArray = {a collection of your objects};

usort($myArray, 'myCompare');

Bu PHP Kılavuzunda oldukça fazla bir örnektir, ama umarım şimdi bağlamda mantıklı. Ben bir şey net varlık değilim eğer bana bildirin.

İşte usort() kullanarak başka bir örnek. Bu bir Eğer nesne değişkeni ve sıralama yönünü belirlemenizi sağlar:

function sort_obj_arr(& $arr, $sort_field, $sort_direction)
{
    $sort_func = function($obj_1, $obj_2) use ($sort_field, $sort_direction)
    {
        if ($sort_direction == SORT_ASC) {
            return strnatcasecmp($obj_1->$sort_field, $obj_2->$sort_field);
        } else {
            return strnatcasecmp($obj_2->$sort_field, $obj_1->$sort_field);
        }
    };
    usort($arr, $sort_func);
}

Test kod;

class TestClass
{
    public $name;
    public $age;

    public function __construct($name, $age)
    {
        $this->name = $name;
        $this->age  = $age;
    }
}

$test[] = new TestClass('Tom', 28);
$test[] = new TestClass('Mary', 48);
$test[] = new TestClass('Beth', 38);
$test[] = new TestClass('Cindy', 18);
$test[] = new TestClass('Sid', 58);
$test[] = new TestClass('Mandy', 8);

$field = 'age';
$direction = SORT_DESC;
sort_obj_arr($test, $field, $direction);

echo '<pre>';
print_r($test);
echo '</pre>';

Josh Davis'in çözümü bir XML dosyası üzerinden yüklerken çalışmak için görünmüyor:

$nodes = simplexml_load_file('/home/usr/public_html/feeds/deadlines.php');

Ben şu hatayı alıyorum:

Warning: array_multisort() [function.array-multisort]: Argument #3 is expected to be an array or a sort flag in /home/usr/public_html/feeds/deadlines.php on line 8

Bu ilgilidir: array_multisort ($ sort_proxy, $ için, $ düğümleri);

Bir eski konu ama burada benim çözüm olduğundan başlığa göre sıralamak için bir rss feed bilgileri ayıklamak için bir kullanım

$xml =  simplexml_load_file('rss.xml');
$msg = array();
$msg_count = $xml->channel->item->count();

for ($x=0;$x<$msg_count;$x++){
    $msg[$x]['titl'] = (string)$xml->channel->item[$x]->title;
    $msg[$x]['link'] = (string)$xml->channel->item[$x]->link;
    $msg[$x]['date'] = (string)$xml->channel->item[$x]->pubDate;
    $msg[$x]['time'] = strtotime(substr((string)$xml->channel->item[$x]->pubDate,4));
    $msg[$x]['desc'] = (string)$xml->channel->item[$x]->description;
    $msg[$x]['auth'] = (string)$xml->channel->item[$x]->author;
}

foreach ($msg as $key => $row) {
    $titl[$key] = $row['titl'];
    $link[$key] = $row['link'];
    $pdat[$key] = $row['date'];
    $time[$key] = $row['time'];
    $cate[$key] = $row['cate'];
    $desc[$key] = $row['desc'];
    $auth[$key] = $row['auth'];
}

array_multisort(
//change $titl to any variable created by "foreach"
    $titl, SORT_ASC,SORT_NATURAL | SORT_FLAG_CASE,
    $msg);