print order of assoctive array

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • pauld

    #1

    print order of assoctive array



    Ive got a series of 2 dimensional associative arrays
    while(list($key , $val) = each ($results))
    {
    {foreach($val as $i=>$v)
    print "$i = $v";
    }
    }


    but i want to define the order that the various $i's are printed in
    (not numerical/alphabetically)

    arrays named
    "key1_sorted_or der" = keys in the order to be printed
    "key2_sorted_or der"

    ive been experimeting with

    while(list($key , $val) = each ($results))
    {
    {foreach($val as $i=>$v)
    $ks=$i.'_sorted _order';
    ($cntr=0;cntr<c ount($ks);$cntr ++ )
    { print [$ks[$cntr]] =$results[$val[$ks[$cntr]]]
    }
    }
    }

    anyone able to help me out ?

  • Erwin Moller

    #2
    Re: print order of assoctive array

    pauld wrote:
    [color=blue]
    >
    >
    > Ive got a series of 2 dimensional associative arrays
    > while(list($key , $val) = each ($results))
    > {
    > {foreach($val as $i=>$v)
    > print "$i = $v";
    > }
    > }
    >
    >
    > but i want to define the order that the various $i's are printed in
    > (not numerical/alphabetically)
    >
    > arrays named
    > "key1_sorted_or der" = keys in the order to be printed
    > "key2_sorted_or der"
    >
    > ive been experimeting with
    >
    > while(list($key , $val) = each ($results))
    > {
    > {foreach($val as $i=>$v)
    > $ks=$i.'_sorted _order';
    > ($cntr=0;cntr<c ount($ks);$cntr ++ )
    > { print [$ks[$cntr]] =$results[$val[$ks[$cntr]]]
    > }
    > }
    > }
    >
    > anyone able to help me out ?[/color]

    Hi,

    I just wrote a similar routine yesterday. :-)
    Try this:

    Move every element in your array to a new array, using an assoc-index of
    your choice, and thus defining the ordering.
    ksort ($newarray)

    Works like a charm.

    If the default ksort is not to your liking, use uksort.

    Good luck

    Regards,
    Erwin Moller

    Comment

    • Ewoud Dronkert

      #3
      Re: print order of assoctive array

      Erwin Moller wrote:[color=blue]
      > Move every element in your array to a new array[/color]

      Why? Just apply uksort to $val (the 2nd level array).

      --
      E. Dronkert

      Comment

      • pauld

        #4
        Re: print order of assoctive array

        I read that but couldnt see how to apply it

        the keys in the assoc array and the order id like then to appear are


        ('21', 'NC2', 'NC4', '28', '35', '40', '50', '60', '80', '100')

        ( if you are interested its the % oxygen you can administer )

        Comment

        • Ewoud Dronkert

          #5
          Re: print order of assoctive array

          pauld wrote:[color=blue]
          > the keys in the assoc array and the order id like then to appear are
          > ('21', 'NC2', 'NC4', '28', '35', '40', '50', '60', '80', '100')[/color]

          $oxchr = array('21', 'NC2', 'NC4', '28', '35', '40', '50', '60', '80',
          '100');
          $oxord = array_flip($oxc hr);

          function oxkeysort($k1, $k2) {
          global $oxord;
          return $oxord[$k1] - $oxord[$k2];
          }

          uksort($val, 'oxkeysort');

          --
          E. Dronkert

          Comment

          • Erwin Moller

            #6
            Re: print order of assoctive array

            Ewoud Dronkert wrote:
            [color=blue]
            > Erwin Moller wrote:[color=green]
            >> Move every element in your array to a new array[/color]
            >
            > Why? Just apply uksort to $val (the 2nd level array).[/color]

            Hi Ewoud,

            Yes, you are right.

            The situation I was describing was an array with a complex structure per
            element that it contained (more arrays actually, but complex sounds so
            great).

            The underlying arraystructure differed from element to element.

            For some stupid reason I thought the function called by uksort could only
            operate on single simple values, which turned out to be nonsense.
            (I guess I guessed wrong, based on my experiences with Java, where that
            logic is just implemented a little differently for sorting.)

            I reread the uksort-function, and the function used just receives the
            elements, which can be used to look deeper into their arrays.

            Anyway, I got it now.
            I will be using uksort a lot more now, so thanks.

            You just made my life a little easier (and my code a little faster).
            :-)

            Regards,
            Erwin Moller

            Comment

            • pauld

              #7
              Re: print order of assoctive array

              thanks -great help. Got the first one working not sure i quite
              understand it though (!)
              the added problem is that I have a series of these and would ideally
              like to to generate the array name dynamically.The array_push is an
              attempt to make the code generic

              eg for 2 of them I can do

              if ($key=="oxy") {
              foreach($oxysor ted as $v)
              {array_push($so rted,$v);}
              $oxord = array_flip($sor ted);
              uksort($val, 'keysort');
              print '<table summary="" border=2>';
              foreach($val as $i=>$v){print '<tr><td>'.$i." =>".$v.'</td></tr>';
              }
              }
              else if ($key=="physio" ) {
              foreach($physio sorted as $v){array_push( $sorted,$v);}
              $oxord = array_flip($sor ted);
              uksort($val, 'keysort');
              print '<table summary="" border=2>';
              foreach($val as $i=>$v){print '<tr><td>'.$i." =>".$v.'</td></tr>';
              }
              }

              Ive tried genertign the array name dynamically but it doesnt revognise
              it as an array
              eg
              $varsorted=$key .'sorted';
              and replacing the ($oxysorted as $v) and ($physiosorted as $v) with
              ($varsorted as $v) but it doenst like it .

              I *think* its the php equivalent of perls $$variable that Im after

              Comment

              • Ewoud Dronkert

                #8
                Re: print order of assoctive array

                pauld wrote:[color=blue]
                > the added problem is that I have a series of these and would ideally
                > like to to generate the array name dynamically.[/color]

                First an explanation of what I wrote earlier:

                $oxchr = array(
                '21', 'NC2', 'NC4', '28', '35', '40', '50', '60', '80', '100');
                $oxord = array_flip($oxc hr);

                function oxkeysort($k1, $k2) {
                global $oxord;
                return $oxord[$k1] - $oxord[$k2];
                }

                uksort($val, 'oxkeysort');

                The $oxchr array contains all the keys of the array that you want sorted,
                in the order that you want them sorted. Not shown but implied by omitting
                them are the numerical keys of the $oxchr array, from 0 for '21' to 9 for
                '100'. 'Flipping' an array means switching each key-value pair. So $oxord
                contains array('21' => 0, 'NC2' => 1, ..., '100' => 9). I loaned the
                variable names from the chr() and ord() functions because $oxchr[1] gives
                'NC2' while $oxord['NC2'] gives 1, much the same as chr(65) is 'A' and
                ord('A') is 65. It means you can determine the order of the oxygen label
                keys by accessing the $oxord array. The oxkeysort() function does just
                that by returning the difference between two $oxord values. Zero means
                that the same key was used, negative means that the first was smaller than
                the second (ie. already sorted in ascending order) and positive the
                reverse: 1 was bigger than 2, must be swapped for ascending order.
                Finally, the uksort() function puts it to good use by sorting the $val
                array using the supplied function for comparing the keys of $val, those
                keys being the same oxygen labels defined as values in $oxchr.

                Now, if you want to have more user defined sorting orders, my first
                instinct would be to expand the chr and ord arrays to 2 dimensions:

                $mychr = array(
                'oxy' => array(
                '21', 'NC2', 'NC4', '28', '35', '40', '50', '60', '80', '100'),
                'physio' => array(
                'John', 'Joe', 'Anne', 'Marie'));
                $myord = array();
                foreach ($mychr as $k => $v)
                $myord[$k] = array_flip($v);

                So $mychr['oxy'] is the same as $oxchr previously, likewise $myord['oxy']
                and $oxord. In addition, you now have $myord['physio'].

                My second idea would be to maintain the idea of my first code snippet: to
                use a global variable in the user defined sort function for accessing the
                sort order. But that order can now be different each time. So use a
                "pointer" to the currently used one:

                $curord = 'oxy';
                function mykeysort($k1, $k2) {
                global $myord, $curord;
                return $myord[$curord][$k1] - $myord[$curord][$k2];
                }

                Or perhaps one level up for slightly simpler code inside the function,
                although speed of execution could go either way depending on size of the
                arrays and calling frequency of the different functions:

                $curord = $myord['oxy'];
                function mykeysort($k1, $k2) {
                global $curord;
                return $curord[$k1] - $curord[$k2];
                }

                Of course, the global $curord need not be set right away. Each time before
                you call uksort(), first set the appropriate sort order:

                $curord = 'oxy'; //or $curord = $myord['oxy'];
                uksort($val, 'mykeysort'); //$val contains oxygen label keys

                $curord = 'physio'; //or $curord = $myord['physio'];
                uksort($val, 'mykeysort'); //$val contains physio label keys

                As you can see, the function name inside uksort() doesn't change. You must
                update $curord each time though, which I think you can do "dynamicall y".

                --
                E. Dronkert

                Comment

                Working...