排序的SimpleXML对象的数组排序的SimpleXML对象的数组(Sorting an arra

2019-05-12 08:02发布

我读过,我#2发现我还是对这个不清楚。

我的SimpleXML对象的数组是这样的:

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"
  }
}

我希望能够通过任何列排序,上升或下降。 就像是:

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

我在哪里可以通过取其键的我喜欢的值的上述目的和排序的数组中传递。

作为参考,类似的.NET解决方案将是沿着这些路线:

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

我见过的人说

“使用usort”

随后从PHP手册一个基本的例子,但是这并不能真正解释。 至少不是我。 我还看到有人建议使用像SimpleDOM外部库,但我想避免使用外在的东西这个(貌似,虽然我还没有解决这个问题)的小东西。

任何帮助表示赞赏,谢谢!

Answer 1:

我猜人们建议使用SimpleDOM会是我的。 :)

我已经写SimpleDOM ::排序()正是针对这种情况,因为为了通过仲裁表达(或任意表达式)SimpleXMLElements你需要使用排序array_multisort()这是无聊,也不会教你任何用处。

下面是它是如何工作的短版:你首先创建对应于每个的SimpleXMLElement和与它们将被排序值键=>值对代理服务器阵列。 在您的例子,如果你想对它们进行排序<age/>该阵列是array(21, 56) 然后调用array_multisort()与“代理服务器阵列”作为第一个参数,随后通过任何数量的排序改性剂如SORT_DESC或SORT_NUMERIC然后最终要排序的阵列,这将在通过引用传递。

您将结束与类似的东西:

$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);

不过说真的,而不是用更多的代码负担自己,你必须保持和可能结束了重写array_multisort()在用户空间,你应该充分利用现有的解决方案。 有没有在这样的排序算法/例行有趣,你最好将时间花费在不存在的东西。



Answer 2:

usort功能允许你告诉PHP

嘿,你! 排序这阵我给你这个功能我写的。

它没有什么特别做的SimpleXML。 这对分拣PHP内置阵列数据收集的通用功能。

你需要编写一个函数,实例方法,或数组排序静态方法。 第二个参数usort接受PHP回调 ,这是一个伪类型,让你指定哪个函数,实例方法或静态方法。

你写的函数将接受两个参数。 这将是从你的阵列两个不同的值

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

你需要写这个函数返回三个值中的一个。

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

当你调用usort,PHP将通过你的阵列上运行,呼唤你的分选功能/方法(在这种情况下, cmp一遍又一遍,直到数组进行排序。在您的例子,$ a和$ b会的SimpleXML对象。



Answer 3:

我准备建议usort()直到我意识到你已经打我给它。 由于代码示例均没有过去做了很多很好的,我会尽量只解释它用简单的英语,希望这会让你在正确的方向。

通过使用usort()您创建自己的用户生成的“算法”。 该usort()函数调用自己的比较函数来确定如何每个对象涉及到彼此。 当写你比较函数,你会在两个对象获得通过您的数组中。 有了这两个对象,返回结果基本上告诉usort()的第一个对象是否是LESS THANEQUAL TO ,或GREATER THAN第二个对象。 您可以通过返回-1,0,或1(分别)做到这一点。 而已。 你只有两个对象如何互相比较和实际排序机制被处理的关心自己usort()为您服务。

好了,现在一个半实际的例子:

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');

这是相当多的PHP手册中的例子,但希望它现在在上下文中才有意义。 让我知道如果我不是东西清楚。



Answer 4:

乔希·戴维斯的解决方案似乎没有通过加载XML文件时的工作:

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

我得到以下错误:

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

它涉及到:在array_multisort($ sort_proxy,$顺序,$节点);



Answer 5:

下面是使用的另一个例子usort() 这一个允许你指定的对象变量和排序方向:

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);
}

测试代码;

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


Answer 6:

这是一个古老的线程,但这里是我的解决方案,它使用一个从RSS提要,以便按标题排序中提取信息

$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); 


文章来源: Sorting an array of SimpleXML objects