Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Sorting multidimensional array

    I have a muli-dimensional array (see below).

    I'm trying to use PHP to group matching events. Basically any matchname that is a duplicate (eg. Reds vs Whites) to group them together and group their linksets...

    Code:
    Array
    (
        [matches] => Array
            (
                [match] => Array
                    (
                        [0] => SimpleXMLElement Object
                            (
                                [sportname] => Football
                                [tournamentname] => Crown League
                                [thetime] => 201308021600
                                [matchname] => Reds vs Whites
                                [linkset] => SimpleXMLElement Object
                                    (
                                        [link] => link1.html
                                        [link] => link3.html
                                    )
    
    
                            )
    
                        [1] => SimpleXMLElement Object
                            (
                                [sportname] => Football
                                [tournamentname] => Prince League
                                [thetime] => 201308021130
                                [matchname] => Blues vs Yellows
                                [linkset] => SimpleXMLElement Object
                                    (
                                        [link] => link2.html
                                    )
    
                            )
    
                        [2] => SimpleXMLElement Object
                            (
                                [sportname] => SimpleXMLElement Object
                                [tournamentname] => SimpleXMLElement Object
                                [thetime] => 201308020930
                                [matchname] => Reds vs Whites
                               [linkset] => SimpleXMLElement Object
                                    (
                                        [link] => link4.html
                                    )
    
    
                            )
                            
                            
                             )
                            )
                           )
    I am trying to end up with
    Football: Reds vs Whites (201308021600) - Crown League
    Links: link1.html, link3.html, link4.html

    Football: Blues vs Yellows (201308021130) - Prince League
    Links: link2.html

    I've been looking at the PHP manual but tearing my hair out trying to get it to output the above. Any ideas would be most welcome.

    Thanks
    Last edited by denhamd2; 09-01-2013 at 12:01 PM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    This isn't about sorting, its about combining. Sorting would simply change the orders, but you want to combine based on a criteria. Iteration to a copy is typically the easiest approach to dealing with this.
    You are using xml though, which means you may be able to simply this by writing an xpath query for it.
    PHP wise, a simple iteration would be as such (untested; use var_export if you want to give me useful data to test with :P):
    PHP Code:
    $aCopy = array();
    foreach (
    $matches['match'] AS $match)
    {
        if (!isset(
    $aCopy[$match->matchname]))
        {
            
    $aCopy[$match->matchname] = $match;
        }
        else
        {
            foreach (
    $match->linkset AS $link)
            {
                
    $aCopy[$match->match]->linkset->addChild('link'$link);
            }
        }

    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #3
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Hi,

    Many thanks for the reply. I tried your code but get the error:
    Invalid argument supplied for foreach() in /home/freefoot/public_html/newsite/read_01_09_13.php on line 21

    Here is my code in full - I'm converting an XML file into the array first, then comes the code you gave...

    PHP Code:
    <?php
        $xml 
    simplexml_load_file('test5.xml');





    function 
    xml2array $xmlObject$out = array () )
    {
        foreach ( (array) 
    $xmlObject as $index => $node )
            
    $out[$index] = ( is_object $node ) ) ? xml2array $node ) : $node;

        return 
    $out;
    }
    $array XML2Array($xml);
    $array = array($xml->getName() => $array);



    $aCopy = array();
    foreach (
    $array['match'] AS $match)
    {
        if (!isset(
    $aCopy[$match->matchname]))
        {
            
    $aCopy[$match->matchname] = $match;
        }
        else
        {
            foreach (
    $match->linkset AS $link)
            {
                
    $aCopy[$match->match]->linkset->addChild('link'$link);
            }
        }
    }  

    var_export($aCopy);

    ?>
    Any ideas?

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Use $array['matches']['match'] as your iterative array.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #5
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thanks. When I update it now I got a repeating error:

    Warning: Illegal offset type in isset or empty in /home/freefoot/public_html/newsite/read_01_09_13.php on line 23
    Warning: Illegal offset type in /home/freefoot/public_html/newsite/read_01_09_13.php on line 25

    I googled the error and edited the code a little ($aCopy["{$match->matchname}"]):

    PHP Code:
    <?php 
        $xml 
    simplexml_load_file('test5.xml'); 





    function 
    xml2array $xmlObject$out = array () ) 

        foreach ( (array) 
    $xmlObject as $index => $node 
            
    $out[$index] = ( is_object $node ) ) ? xml2array $node ) : $node

        return 
    $out

    $array XML2Array($xml); 
    $array = array($xml->getName() => $array); 



    $aCopy = array(); 
    foreach (
    $array['matches']['match'] AS $match

        if (!isset(
    $aCopy["{$match->matchname}"]))
        { 
            
    $aCopy["{$match->matchname}"] = $match
        } 
        else 
        { 
            foreach (
    $match->linkset AS $link
            { 
                
    $aCopy["{$match->match}"]->linkset->addChild('link'$link); 
            } 
        } 
    }   

    var_export($aCopy); 

    ?>
    But I now get the error:
    Fatal error: Call to a member function addChild() on a non-object in /home/freefoot/public_html/newsite/read_01_09_13.php on line 31

    Any idea what could be going wrong? I think its something on this line...
    Code:
     $aCopy["{$match->match}"]->linkset->addChild('link', $link);
    Last edited by denhamd2; 09-01-2013 at 07:20 PM.

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Post a var_export of the $array.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #7
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I didn't get access to the var export with the error. However I have now changed that line to...
    $aCopy["{$match->matchname}"]->linkset->addChild('link', $link);
    ... and get the below var export. It looks like its combining ok, but link3 and link4 aren't showing up...

    PHP Code:

    array (
      
    'Reds vs Whites' => 
      
    SimpleXMLElement::__set_state(array(
         
    'sportname' => 'Football',
         
    'tournamentname' => 'Crown League',
         
    'thetime' => '201309011330',
         
    'matchname' => 'Reds vs Whites',
         
    'linkset' => 
        
    SimpleXMLElement::__set_state(array(
           
    'link' => 
          array (
            
    => 'link1.html>',
            
    => 'link2.html',
            
    => 
            
    SimpleXMLElement::__set_state(array(
            )),
          ),
        )),
      )),
      
    'Yellows vs Blues' => 
      
    SimpleXMLElement::__set_state(array(
         
    'sportname' => 'Football',
         
    'tournamentname' => 'Crown League',
         
    'thetime' => '201309012000',
         
    'matchname' => 'Yellows vs Blues',
         
    'linkset' => 
        
    SimpleXMLElement::__set_state(array(
        )),
      )),

    Last edited by denhamd2; 09-01-2013 at 08:00 PM.

  • #8
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Oh yeah these are objects right. And the simplexml seems to have no __set_state override available.
    Serialize the $array instead. I'm not interested in the results of the copy only the original.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #9
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Ok, I've tried...
    $array = serialize($array);
    var_export($array);

    ...and get this error:
    PHP Code:
    <br />
    <
    b>Fatal error</b>:  Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in /home/freefoot/public_html/newsite/read_01_09_13.php:18
    Stack trace
    :
    #0 /home/freefoot/public_html/newsite/read_01_09_13.php(18): serialize(Array)
    #1 {main}

    Next exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in /home/freefoot/public_html/newsite/read_01_09_13.php:18
    Stack trace
    :
    #0 /home/freefoot/public_html/newsite/read_01_09_13.php(0): serialize()
    #1 {main}

    Next exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed' in /home/freefoot/public_html/newsite/read_01_09_13.php:18
    Stack trace
    :
    #0 /home/freefoot/public_html/newsite/read_01_09_13.php(0): serialize()
    #1 {main}
      
    thrown in <b>/home/freefoot/public_html/newsite/read_01_09_13.php</bon line <b>18</b><br /> 
    Any ideas?

  • #10
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Ugh, simplexml just makes me more angry any time I see it.
    What are the results of a the print_r for the $array? The one you have for the var_export above doesn't match the original structure in the first post.
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #11
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    I've now removed the serialize from $array. Here is the print_r of it:

    PHP Code:
    Array
    (
        [
    matches] => Array
            (
                [
    match] => Array
                    (
                        [
    0] => SimpleXMLElement Object
                            
    (
                                [
    sportname] => Football
                                
    [tournamentname] => Crown League
                                
    [thetime] => 201308021600
                                
    [matchname] => Reds vs Whites
                                
    [linkset] => SimpleXMLElement Object
                                    
    (
                                        [
    link] => Array
                                            (
                                                [
    0] => link1.html>
                                                [
    1] => link3.html
                                            
    )

                                    )

                            )

                        [
    1] => SimpleXMLElement Object
                            
    (
                                [
    sportname] => Football
                                
    [tournamentname] => Crown League
                                
    [thetime] => 201308021130
                                
    [matchname] => Blues vs Yellows
                                
    [linkset] => SimpleXMLElement Object
                                    
    (
                                        [
    link] => link2.html
                                    
    )

                            )

                        [
    2] => SimpleXMLElement Object
                            
    (
                                [
    sportname] => Football
                                
    [tournamentname] => Crown League
                                
    [thetime] => 201308020930
                                
    [matchname] => Reds vs Whites
                                
    [linkset] => SimpleXMLElement Object
                                    
    (
                                        [
    link] => link4.html
                                    
    )

                            )

                    )

            )


    btw, is there any way to get SimpleXMLElement Object to stop showing up?

    Thanks again for your help!
    Last edited by denhamd2; 09-02-2013 at 08:39 AM.

  • #12
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    I can't be sure since I don't typically use simplexmlelement's, but I think you should just be able to cast them to arrays if you want arrays. It's not recursive though. It may be easier to just use the simplexmlelement than to use an array though.
    What's the XML that you're using for this?
    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #13
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Here's the XML I'm pulling from:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <matches>
    	<match><sportname>Football</sportname><tournamentname>Crown League</tournamentname><thetime>201308021600</thetime><matchname dateandtime="201308021600">Reds vs Whites</matchname><linkset><link>link1.html></link><link>link3.html</link></linkset></match>
    	<match><sportname>Football</sportname><tournamentname>Crown League</tournamentname><thetime>201308021130</thetime><matchname dateandtime="201308021130">Blues vs Yellows</matchname><linkset><link>link2.html</link></linkset></match>
    	<match><sportname>Football</sportname><tournamentname>Crown League</tournamentname><thetime>201308020930</thetime><matchname dateandtime="201308020930">Reds vs Whites</matchname><linkset><link>link4.html</link></linkset></match>
    </matches>
    Any idea why link4.html isn't showing up in the combined Reds vs Whites match?
    Last edited by denhamd2; 09-02-2013 at 04:23 PM.

  • #14
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Use this:
    PHP Code:
    $xml simplexml_load_file('test5.xml'); 
    $aCopy = array();

    foreach (
    $xml->match AS $match)
    {
        if (!isset(
    $aCopy[(string)$match->matchname]))
        {
            
    $aCopy[(string)$match->matchname] = $match;
        }
        else
        {
            foreach (
    $match->linkset AS $link)
            {
                
    $aCopy[(string)$match->matchname]->linkset->addChild('link'$link->link);
            }
        }

    PHP Code:
    header('HTTP/1.1 420 Enhance Your Calm'); 
    Been gone for a few months, and haven't programmed in that long of a time. Meh, I'll wing it ;)

  • #15
    New Coder
    Join Date
    Sep 2004
    Posts
    96
    Thanks
    1
    Thanked 0 Times in 0 Posts
    Thanks so much, that works now

    I've tried to add in a function which sorts the array by thetime but it doesnt seem to do the job. Sorry to be asking again, I know I'm probably missing something stupid, would you be able to cast an eye over that please?

    Code:
    <?php 
    $xml = simplexml_load_file('test5.xml'); 
    $aCopy = array();
    
    foreach ($xml->match AS $match)
    {
        if (!isset($aCopy[(string)$match->matchname]))
        {
            $aCopy[(string)$match->matchname] = $match;
        }
        else
        {
            foreach ($match->linkset AS $link)
            {
                $aCopy[(string)$match->matchname]->linkset->addChild('link', $link->link);
            }
        }
    }  
    
    
    function array_sort_by_column(&$array, $column, $direction = SORT_ASC) {
        $reference_array = array();
    
        foreach($array as $key => $row) {
            $reference_array[$key] = $row[$column];
        }
    
        array_multisort($reference_array, $direction, $array);
    }
    
    array_sort_by_column($aCopy, 'thetime');
    
    
    print_r($aCopy); 
    
    ?>
    Thanks very much again.


  •  
    Page 1 of 2 12 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •