Solved

Ordering an array and then ordering additional arrays to match

Posted on 2015-02-13
15
112 Views
Last Modified: 2015-02-14
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
Comment
Question by:St_Aug_Beach_Bum
  • 8
  • 6
15 Comments
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40609049
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40609067
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
 
LVL 12

Assisted Solution

by:Phil Phillips
Phil Phillips earned 150 total points
ID: 40609071
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40609075
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40609080
@Phil_Phillips: Exactly!
0
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609100
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
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609355
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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609356
Opps, left off rank:

$rank = Array ( [0] => 1 [1] => 2 [2] => 3 )
0
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609772
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
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609783
Ah, ok, got that part figured out on my own, yea!
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 350 total points
ID: 40609789
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
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 40609790
Ha!  Our posts passed in cyberspace.  I think you're getting it now!

Cheers, ~Ray
0
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40609812
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
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40610058
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
 

Author Comment

by:St_Aug_Beach_Bum
ID: 40610228
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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Suggested Solutions

Developers of all skill levels should learn to use current best practices when developing websites. However many developers, new and old, fall into the trap of using deprecated features because this is what so many tutorials and books tell them to u…
This article discusses how to create an extensible mechanism for linked drop downs.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
The viewer will learn how to dynamically set the form action using jQuery.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now