Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 123
  • Last Modified:

Ordering an array and then ordering additional arrays to match

This is a little messy maybe, but it's what I've got....

I have a number of arrays with matching keys (not sure if I am using the terminology right). [0] in each array goes with the [0] in all the other arrays, [1] in each goes with [1] in the others, ect.

I've spliced them down to the number of elements I want in each:

$rank = array_splice($rank,0,7);
$title = array_splice($title,0,7);
$episode = array_splice($episode,0,7);
$epTime = array_splice($epTime,0,7);
$epSum = array_splice($epSum,0,7);

Now.... I need to re-order the $epTime array by the time that is in it, earlier to later..., but there is some additional information in there... here's the print_r results for that array.

Array ( [0] => 10:00PM | CBS [1] => 9:00PM | CBS [2] => 9:00PM | NBC [3] => 8:00PM | NBC [4] => 9:00PM | Syfy [5] => 9:00PM | FOX [6] => 10:00PM | Syfy )

Then I need all the other arrays ordered so they match up with the $epTime order.  So... for example, if [3] moved to [1] in $epTime, [3] needs to move to [1] in all the other arrays as well.

I don't have a clue as to how to do this...  can you help?

Chris
0
St_Aug_Beach_Bum
Asked:
St_Aug_Beach_Bum
  • 8
  • 6
2 Solutions
 
Ray PaseurCommented:
Probably a good start would be to use the ISO-8601 time representation.  It uses a 24-hour clock, so that the natural differences between 9:00am and 8:00pm are respected.  You can reformat the output for "public consumption" with the PHP date() function.  Full explanation of PHP date/time handling here:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html

Please have a look at the linked article.  I'll try to show you an example in a moment.
0
 
Ray PaseurCommented:
See if this makes sense...
http://iconoun.com/demo/temp_staug.php
<?php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28616855.html
 *
 * ACHTUNG!
 * This solution depends on the information in the array elements.
 * These elements MUST BE UNIQUE
 */
error_reporting(E_ALL);

// TEST DATA FROM THE POST AT EE
$times =
[ '10:00PM | CBS'
, '9:00PM | CBS'
, '9:00PM | NBC'
, '8:00PM | NBC'
, '9:00PM | Syfy'
, '9:00PM | FOX'
, '10:00PM | Syfy'
];

// TRANSFORM THE DATA CREATING ISO-8601 KEYS
$new = [];
foreach ($times as $info)
{
    // BREAK THE STRING BY USING A PIPE SEPARATOR
    $sub = explode('|', $info);
    $ndx = date('H:i:s', strtotime('Today ' . $sub[0]));
    $new[$ndx . $info] = $info;
}

// SORT THE NEW ARRAY BY THE NEW ARRAY KEYS
ksort($new);

// SHOW THE ORIGINAL DATA AND THE WORK PRODUCT
echo '<pre>' . PHP_EOL;

echo 'ORIGINAL:' . PHP_EOL;
print_r($times);
echo PHP_EOL;

echo 'WORK PRODUCT:' . PHP_EOL;
print_r($new);
echo PHP_EOL;

// REMOVE THE KEYS, IN CASE YOU CARE ABOUT STUFF LIKE THAT\
$new = array_values($new);

echo 'WORK PRODUCT WITH KEYS REMOVED:' . PHP_EOL;
print_r($new);
echo PHP_EOL;

Open in new window

0
 
Phil PhillipsDirector of DevOpsCommented:
I agree with Ray on how time should be represented.

You also might want to restructure your data a little bit.  Instead of individual arrays for each field, create an object with those fields.  Then, you can have an array of those objects, and sort that.  This way, everything gets sorted all together.

A very quick example:

<?php
class episode
{
  public $title;
  public $episode;
  public $epTime;
  public $epSum;
  public $rank;

  public function __construct( $title, $episode, $epTime, $epSum, $rank )
  {
    $this->title = $title;
    $this->episode = $episode;
    $this->epTime = $epTime;
    $this->epSum = $epSum;
    $this->rank = $rank;
  }

  public static function compareTime( $a, $b )
  {
    return strtotime($a->epTime)-strtotime($b->epTime);
  }
	
  public static function sortByTime( &$collection)
  {
    usort( $collection, array( __CLASS__, 'compareTime' ) );
  }
}

$episodes = array(
  new episode( 'Star Wars', 'Episode 4', '09:00', 1, 1  ),
  new episode( 'Star Wars', 'Episode 1', '05:00', 1, 6  ),
  new episode( 'Star Wars', 'Episode 6', '07:00', 1, 2  )
);

episode::sortByTime($episodes);

print_r( $episodes );
?>

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
Ray PaseurCommented:
The next step, of course, will be to make a correlation between the original keys and the keys of the sorted data.  But rather than doing that, a better design would be to make an array of arrays or an array of objects and use PHP usort() to order the elements.  Usort() is tricky.  If you can show us the contents of one of the parallel arrays, I can set up an example to show you how its done.
0
 
Ray PaseurCommented:
@Phil_Phillips: Exactly!
0
 
St_Aug_Beach_BumAuthor Commented:
Thank you both, I tried the array of arrays route and just got my brain (and code) tangled in knots. I'm reading through and playing with these codes now... then grabbing some dinner and will be back here with an update - thanks again.
0
 
St_Aug_Beach_BumAuthor Commented:
Ok, I can see how the examples work... kind of.... but not sure how to get the parallel arrays into the examples...

The arrays I have are like this:

$title = Array ( [0] => Blue Bloods [1] => Hawaii Five-0 [2] => Grimm )
$episode = Array ( [0] => Power Players [1] => E 'Imi pono [2] => Trial by Fire )
$epTime = Array ( [0] => 10:00PM | CBS [1] => 9:00PM | CBS [2] => 9:00PM | NBC )
$epSum = Array ( [0] => Summary of BB [1] => Summary of Five-O [2] => Summary of Grim )

(there would be 8 entries in each though.
0
 
St_Aug_Beach_BumAuthor Commented:
Opps, left off rank:

$rank = Array ( [0] => 1 [1] => 2 [2] => 3 )
0
 
St_Aug_Beach_BumAuthor Commented:
So I guess I need to take these arrays:

$title = Array ( [0] => Blue Bloods [1] => Hawaii Five-0 [2] => Grimm )
$episode = Array ( [0] => Power Players [1] => E 'Imi pono [2] => Trial by Fire )
$epTime = Array ( [0] => 10:00PM | CBS [1] => 9:00PM | CBS [2] => 9:00PM | NBC )
$epSum = Array ( [0] => Summary of BB [1] => Summary of Five-O [2] => Summary of Grim )
$rank = Array ( [0] => 1 [1] => 2 [2] => 3 )

and redo them so I can use them like this...

$episodes = array(
  new episode( 'Blue Bloods', 'Power Players','10:00PM | CBS', 'Summary of BB', '1'  ),
  new episode( 'Hawaii Five-0', 'E 'Imi pono', '9:00PM | CBS','Summary of Five-O', '2'  ),
  new episode( 'Grimm', 'Trial by Fire', '9:00PM | NBC','Summary of Grim','3'  )
);
0
 
St_Aug_Beach_BumAuthor Commented:
Ah, ok, got that part figured out on my own, yea!
0
 
Ray PaseurCommented:
This might benefit from a little re-organization of the data.  In the examples here, we have put the data together into an array of objects.  Objects are useful for organizing related data elements, and the array makes it easy to work with a collection of objects.  That point seems to have been overlooked in your implementation of the earlier example.  Here's some annotation of the script below...

Line 18-36 defines a Class.  The Class definition is used to create an object.  Think of the Class as being a blueprint.  It tells the structure of the Object, but is not the Object, and by itself, it is not useful except as an organizational tool.  But in this case it's a very good organizational tool since it neatly groups all of the related data together, much like the rows of a database or spreadsheet would group related data together.  Ref: http://php.net/manual/en/language.oop5.php

Line 32-35 defines a Class "Method."  Methods are functions that are defined in the context of the class and that can operate on the data inside the object (this data is called the "properties" of the object).  In this case, the object automatically calls this method, converts the non-standard date/time values into standardized values, and assigns the standardized value to a property of the object.  With a well-organized class structure, you can have a lot of things like this that happen "automagically."

Line 39-46 consists of some test data.  The code here creates an array of objects.  Each time a new object is added to the array, PHP uses the TVData Class defined above as the template.  The class constructor (a special method named __construct() is automatically run.  As you can see from the TVData definition, the constructor copies some data fields into object properties.  You can tell they are object properties because they all start with $this->

Line 49-56 defines and applies a user-sort function.  Same with line 59-66.  These functions (or functions like them) can be applied to re-order the objects in the array into any sequence that makes sense for your application.

<?php

/**
 * See http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/Q_28616855.html#a40609355
 *
 * ORIGINAL DATA FROM THE POST AT EE SEEMS TO HAVE ROWS AND COLUMNS INVERTED
 *
 * $title = Array ( [0] => Blue Bloods [1] => Hawaii Five-0 [2] => Grimm )
 * $episode = Array ( [0] => Power Players [1] => E 'Imi pono [2] => Trial by Fire )
 * $epTime = Array ( [0] => 10:00PM | CBS [1] => 9:00PM | CBS [2] => 9:00PM | NBC )
 * $epSum = Array ( [0] => Summary of BB [1] => Summary of Five-O [2] => Summary of Grim )
 *
 */
error_reporting(E_ALL);
echo '<pre>';


// CREATE A SIMPLE CLASS TO REPRESENT THE INFORMATION
Class TVData
{
    public function __construct($title, $episode, $time, $network, $summary)
    {
        $this->title   = $title;
        $this->episode = $episode;
        $this->time    = $time;
        $this->network = $network;
        $this->summary = $summary;

        $this->standardizeTime();
    }

    protected function standardizeTime()
    {
        $this->standard_time = date('H:i:s', strtotime('Today ' . $this->time));
    }
}


// CREATE THE ARRAY OF OBJECTS
$arr = array
( new TvData( 'Blue Bloods',   'Power Players',  '10:00PM', 'CBS', 'Summary of BB' )
, new TvData( 'Hawaii Five-0', "E 'Imi pono",    '9:00PM',  'CBS', 'Summary of Five-O' )
, new TvData( 'Grimm',         'Trial by Fire',  '9:00PM',  'NBC', 'Summary of Grim' )
, new TvData( '2020',          'Family Secrets', '8:00PM',  'ABC', 'Summary of 2020' )
)
;


// DEFINE AND APPLY A USER-SORT FUNCTION
function time_comparison_callback($a, $b)
{
    if     ($a->standard_time == $b->standard_time) return 0;
    return ($a->standard_time <  $b->standard_time) ? -1 : 1;
}
usort($arr, 'time_comparison_callback');
print_r($arr);


// DEFINE AND APPLY A MULTI-COLUMN USER-SORT FUNCTION
function complex_comparison_callback($a, $b)
{
    if     ($a->network . $a->standard_time == $b->network . $b->standard_time) return 0;
    return ($a->network . $a->standard_time <  $b->network . $b->standard_time) ? -1 : 1;
}
usort($arr, 'complex_comparison_callback');
print_r($arr);

Open in new window

0
 
Ray PaseurCommented:
Ha!  Our posts passed in cyberspace.  I think you're getting it now!

Cheers, ~Ray
0
 
St_Aug_Beach_BumAuthor Commented:
No, thank you so much, glad they past each other because my solution didn't work out so good :)  Picking through this now to see how it works...
0
 
St_Aug_Beach_BumAuthor Commented:
Very cool... now I have an array with everything I need and in the order I need it...

Just one more thing... I'm not used to working with objects and I'm not sure how to display the information.

This is the results of print_r($arr);

Array ( [0] => TVData Object ( [rank] => 4 [title] => Constantine [episode] => Waiting for the Man (Season 1 | Episode 13) [time] => 8:00PM [network] => NBC [summary] => John and Zed return... [standard_time] => 20:00:00 ) [1] => TVData Object ( [rank] => 9 [title] => Undercover Boss [episode] => Rivers of Gold [time] => 8:00PM [network] => CBS [summary] => Gigi Butler, founder... [standard_time] => 20:00:00 ) [2] => TVData Object ( [rank] => 6 [title] => Glee [episode] => Transitioning (Season 6 | Episode 7) [time] => 9:00PM [network] => FOX [summary] => Will takes a... [standard_time] => 21:00:00 ) [3] => TVData Object ( [rank] => 8 [title] => Shark Tank [episode] => Gigi's Cupcakes (Season 6 | Episode 11) [time] => 9:00PM [network] => ABC [summary] => A Portland, Ore., couple... [standard_time] => 21:00:00 ) [4] => TVData Object ( [rank] => 5 [title] => 12 Monkeys [episode] => The Night Room (Season 1 | Episode 5) [time] => 9:00PM [network] => Syfy [summary] => Cole and Dr. Railly... [standard_time] => 21:00:00 ))

So... how do I print or echo, for example, the 'title' of the first result?

I read in a forum to do it like this:

echo $arr['title'][0];

...that doesn't work.

Thanks, you've gone above and beyond the call with this one. I always have ideas for things that are out of reach of what I know how to do!
0
 
St_Aug_Beach_BumAuthor Commented:
Found it :)  Surprisingly well hidden information. I'm using:  echo $arr[0]->title;  Is that what you would have suggested?

Ok, now have to figure out points. I'd give both of you 500 if I could, hmmm.

I answer questions in a google help forum, I know it takes a lot of time and dedication to help people. I really appreciate the help and I thank you.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now