View Full Version : Collapse an Array
jdadwilson
05-06-2013, 11:28 PM
I am in the process of placing several high school yearbooks online for a client. All page have been scanned and a db table created to index the names and associated page numbers. From the table I wish to extract selected information for display. For example, name, year, and page number. I could simply list them in order by name, year and page, such as...
Albert 1957 14
Jones 1958 8
Smith 1958 12
But, because a person may appear on multiple pages in the same yearbook and also in multiple yearbooks the display can appear as...
Albert, Joe 1957 14
Albert, Joe 1957 17
Albert, Joe 1958 12
Albert, Joe 1959 18
Thus, I would like to present the display as...
Albert, Joe 1957/14, 17 - 1958/12 - 1959/18
I have converted the db query result into an array such as $array[0]['name']['year']['page'].
So, the question is... Is there anyway via an array function to "collapse" an array so that the elements from a page for the same name/year would collapse into an array, and then those elements from a year for the same name would collapse into an array?
TIA for your assistance
jdadwilson
jscheuer1
05-07-2013, 01:04 AM
Just for clarification, do you mean:
<?php
$test = array(
array('Albert, Joe', 1957, 14),
array('Albert, Joe', 1957, 17),
array('Albert, Joe', 1958, 12),
array('Albert, Joe', 1959, 18)
);
?>
<pre>
<?php
print_r($test);
?>
</pre>
Which gives:
Array
(
[0] => Array
(
[0] => Albert, Joe
[1] => 1957
[2] => 14
)
[1] => Array
(
[0] => Albert, Joe
[1] => 1957
[2] => 17
)
[2] => Array
(
[0] => Albert, Joe
[1] => 1958
[2] => 12
)
[3] => Array
(
[0] => Albert, Joe
[1] => 1959
[2] => 18
)
)
?
jdadwilson
05-07-2013, 02:15 AM
That would be it.
jscheuer1
05-07-2013, 02:53 AM
OK, give this a shot then:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.yearbookindex {
font: normal 95% verdana, helvetical, arial, sans-serif;
}
</style>
</head>
<body>
<?php
$test = array(
array('Albert, Joe', 1957, 14),
array('Albert, Joe', 1957, 17),
array('Albert, Joe', 1958, 12),
array('Albert, Joe', 1959, 18),
array('Swift, Mary', 1957, 14),
array('Swift, Mary', 1958, 14),
array('Swift, Mary', 1958, 16),
array('Swift, Mary', 1960, 22),
array('Cartwright, Angela', 2017, 212)
);
?>
<div class="yearbookindex">
<?php
$sorted = array();
foreach($test as $entry){
if(!isset($sorted[$entry[0]])){
$sorted[$entry[0]] = array($entry[1] => $entry[2]);
} else if(isset($sorted[$entry[0]][$entry[1]])){
$sorted[$entry[0]][$entry[1]] .= ', ' . $entry[2];
} else {
$sorted[$entry[0]][$entry[1]] = $entry[2];
}
}
foreach ($sorted as $name => $years){
$temp = $name;
$count = count($years);
foreach ($years as $year => $pages){
$temp .= ' ' . $year . '/' . $pages;
if(--$count){
$temp .= ' -';
}
}
$write[] = $temp;
}
echo implode("<br>", $write);
?>
</div>
</body>
</html>
I'm not 100% sure how it will perform with more names, but it should be OK. As you can see I added a few. If there are problems, give me a more representative array to work from (one with several names, each with at least one year/page, some with two or more pages per year, some with more years, etc.), and it can probably be tweaked.
Also, I'm pretty much a beginner at PHP, though I'm very advanced at arrays in general. Which means that as workable as this may be, there might be a more efficient way to do it in PHP.
jdadwilson
05-07-2013, 03:36 AM
John;
Thanks for the input, I'll give it a try.
Probably should have included this link the my original post...
http://www.txfannin.org/yearbooks.php?school=105<r=M
This is what I currently have coded. As you can see it would be a much better presentation without all of the extra lines.
Again, thanks for your assistance. I'll let you know how it goes.
jdadwilson
jdadwilson
05-07-2013, 04:47 AM
John;
Check it out... it works!!!
http://www.txfannin.org/yearbooks_test.php?school=105<r=M
Kinda shot myself in the foot though. The names should be separated from the year/page info. I also need to link the page numbers to the images. Here is a normal page...
http://www.txfannin.org/yearbooks.php?school=105<r=M
Thanks for the code.
jdadwilson
jscheuer1
05-07-2013, 04:52 AM
I'm not sure where the images would come from. But to otherwise approximate that layout, we could do more like so:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.yearbookindex {
font: normal 95% verdana, helvetical, arial, sans-serif;
width: 500px;
border-collapse: collapse;
}
.name {
width: 200px;
}
.datepages {
text-align: right;
}
.odd {
background-color: #f7f6f3;
}
.even {
background-color: #DFDCCF;
}
.yearbookindex tr.even:hover, .yearbookindex tr.odd:hover {
background-color: rgb(174, 167, 134);
}
</style>
</head>
<body>
<?php
$test = array(
array('Albert, Joe', 1957, 14),
array('Albert, Joe', 1957, 17),
array('Albert, Joe', 1958, 12),
array('Albert, Joe', 1959, 18),
array('Swift, Mary', 1957, 14),
array('Swift, Mary', 1958, 14),
array('Swift, Mary', 1958, 16),
array('Swift, Mary', 1960, 22),
array('Cartwright, Angela', 2017, 212)
);
$sorted = array();
foreach($test as $entry){
if(!isset($sorted[$entry[0]])){
$sorted[$entry[0]] = array($entry[1] => $entry[2]);
} else if(isset($sorted[$entry[0]][$entry[1]])){
$sorted[$entry[0]][$entry[1]] .= ", $entry[2]";
} else {
$sorted[$entry[0]][$entry[1]] = $entry[2];
}
}
$rows = -1;
foreach ($sorted as $name => $years){
$temp = "<tr class='" . (++$rows % 2? 'even' : 'odd') . "'><td class='name'>$name</td><td class='datepages'>";
$count = count($years);
foreach ($years as $year => $pages){
$temp .= "$year/$pages";
if(!--$count){$temp .= '</td></tr>';}
else{$temp .= ' - ';}
}
$write[] = $temp;
}
?>
<table class="yearbookindex">
<tr>
<th class="name">Last Name, Other</th>
<th>Year(s) / Page(s)</th>
</tr>
<?php
echo implode("\n", $write);
?>
</table>
</body>
</html>
If the image links could come from the database, I'm sure it wouldn't be too hard to add them in to the listings.
jdadwilson
05-07-2013, 05:21 AM
The image links are generated from information from the database (school ID, year, and page #) see example http://www.txfannin.org/yearbooks.php?school=105<r=M
What you suggested is basically what I have coded.
I just need to wrap the <a> tags around the individual page numbers.
Again, thanks...
jdadwilson
jdadwilson
05-07-2013, 05:38 AM
Final product: http://www.txfannin.org/yearbooks_test.php?school=105<r=M
Thanks for your great code.
jdadwilson
jscheuer1
05-07-2013, 04:03 PM
Looks good. However, in narrower windows/screens the names wrap and it looks a little bad. That could be avoided by adding:
white-space: nowrap;
to the td.udatal, th.udatal selector:
td.udatal, th.udatal {
height:22px;
text-align:left;
padding-left:0.5em;
border-bottom:1px solid #000000;
white-space: nowrap;
}
And I would change the padding:
td.udatal, th.udatal {
height:22px;
text-align:left;
padding: 0 0.5em;
border-bottom:1px solid #000000;
white-space: nowrap;
}
To make the right edge of the table look nicer when it's filled with dates/pages.
Only problem is, I'm not sure where that is. It's on the txfannin.org/files_css/chg_constants.php?c=styles_tables.css stylesheet, which is generated in part by PHP.
You could just add its rules to a stylesheet in the head of the page, just make sure it comes after the link to that txfannin.org/files_css/chg_constants.php?c=styles_tables.css stylesheet.
And you also have to make sure that making this change will not mess up any existing pages you have that you intend to keep.
Alternatively those styles could be added elsewhere and/or in a different way, in a way that cannot affect other content.
jdadwilson
05-07-2013, 05:15 PM
Thanks for the no-wrap suggestion. I added that to the style sheet.
I changed the padding to 0.25 vs 0.5. I want a little space on the left side since some tables in other places will have a border around the full table.
Thanks, does not seem to adequately express my gratitude for your assistance. You guys at DD are the best.
jdadwilson
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.