Am looking over the PHP manual on Array Sorting but cannot seem to get this in the proper order.
Basically in my PHP script I'm getting an array of Year Make Models and Engines, and then using array_unique
to get only the unique Year Make and Models.
Array
(
[0] => 2012 Jeep Liberty
[7] => 2011 Jeep Liberty
[12] => 2010 Jeep Liberty
[15] => 2009 Jeep Liberty
[18] => 2008 Jeep Liberty
[22] => 2007 Jeep Liberty
[26] => 2006 Jeep Liberty
[33] => 2006 Jeep Wrangler
[44] => 2005 Jeep Liberty
[51] => 2005 Jeep Wrangler
[60] => 2004 Jeep Liberty
[64] => 2004 Jeep Wrangler
[73] => 2003 Jeep Liberty
[77] => 2003 Jeep Wrangler
[86] => 2002 Jeep Liberty
[92] => 2002 Jeep Wrangler
[96] => 2001 Jeep Cherokee
[102] => 2001 Jeep Wrangler
[106] => 2000 Jeep Cherokee
[114] => 2000 Jeep Wrangler
[117] => 1999 Jeep Cherokee
[125] => 1999 Jeep Wrangler
[128] => 1998 Jeep Cherokee
[136] => 1998 Jeep Grand Cherokee
[149] => 1998 Jeep Wrangler
[152] => 1997 Jeep Cherokee
[159] => 1997 Jeep Grand Cherokee
[169] => 1997 Jeep Wrangler
[173] => 1996 Jeep Cherokee
[181] => 1996 Jeep Grand Cherokee
[186] => 1995 Jeep Cherokee
[193] => 1995 Jeep Grand Cherokee
[203] => 1995 Jeep Wrangler
)
What I'm trying to do is sort the array so, not only the years match up, but also the Make and Model. Something like:
Array
(
[0] => 2012 Jeep Liberty
[7] => 2011 Jeep Liberty
[12] => 2010 Jeep Liberty
[15] => 2009 Jeep Liberty
[18] => 2008 Jeep Liberty
[22] => 2007 Jeep Liberty
[26] => 2006 Jeep Liberty
[44] => 2005 Jeep Liberty
[60] => 2004 Jeep Liberty
[73] => 2003 Jeep Liberty
[86] => 2002 Jeep Liberty
[33] => 2006 Jeep Wrangler
[51] => 2005 Jeep Wrangler
[64] => 2004 Jeep Wrangler
[77] => 2003 Jeep Wrangler
[92] => 2002 Jeep Wrangler
[102] => 2001 Jeep Wrangler
[114] => 2000 Jeep Wrangler
[125] => 1999 Jeep Wrangler
[149] => 1998 Jeep Wrangler
[169] => 1997 Jeep Wrangler
[203] => 1995 Jeep Wrangler
[96] => 2001 Jeep Cherokee
[106] => 2000 Jeep Cherokee
[117] => 1999 Jeep Cherokee
[128] => 1998 Jeep Cherokee
[152] => 1997 Jeep Cherokee
[173] => 1996 Jeep Cherokee
[186] => 1995 Jeep Cherokee
[136] => 1998 Jeep Grand Cherokee
[159] => 1997 Jeep Grand Cherokee
[181] => 1996 Jeep Grand Cherokee
[193] => 1995 Jeep Grand Cherokee
)
Or something of that nature (sorted this manually, I will probably do a array_values on the array to re-index the keys) -- I just want the Years and the Make/Models to be sorted properly.
What is my best option here?
If you want to sort first the Maker and Model, you can make something like this (assuming the years always have four digits):
<?php
usort(
$array,
function ($value1, $value2) {
$parts1 = explode(' ', $value1, 2);
$parts2 = explode(' ', $value2, 2);
return strcasecmp(
"$parts1[1] $parts1[0]",
"$parts2[1] $parts2[0]"
);
}
);
print_r($array);
The trick was to rearrange the strings when comparing the order, for instance, "Jeep Cherokee 1995".
Output:
Array
(
[0] => 1995 Jeep Cherokee
[1] => 1996 Jeep Cherokee
[2] => 1997 Jeep Cherokee
[3] => 1998 Jeep Cherokee
[4] => 1999 Jeep Cherokee
[5] => 2000 Jeep Cherokee
[6] => 2001 Jeep Cherokee
[7] => 1995 Jeep Grand Cherokee
[8] => 1996 Jeep Grand Cherokee
[9] => 1997 Jeep Grand Cherokee
[10] => 1998 Jeep Grand Cherokee
[11] => 2002 Jeep Liberty
[12] => 2003 Jeep Liberty
[13] => 2004 Jeep Liberty
[14] => 2005 Jeep Liberty
[15] => 2006 Jeep Liberty
[16] => 2007 Jeep Liberty
[17] => 2008 Jeep Liberty
[18] => 2009 Jeep Liberty
[19] => 2010 Jeep Liberty
[20] => 2011 Jeep Liberty
[21] => 2012 Jeep Liberty
[22] => 1995 Jeep Wrangler
[23] => 1997 Jeep Wrangler
[24] => 1998 Jeep Wrangler
[25] => 1999 Jeep Wrangler
[26] => 2000 Jeep Wrangler
[27] => 2001 Jeep Wrangler
[28] => 2002 Jeep Wrangler
[29] => 2003 Jeep Wrangler
[30] => 2004 Jeep Wrangler
[31] => 2005 Jeep Wrangler
[32] => 2006 Jeep Wrangler
)
Here's another solution (without the previous assumption):
<?php
$enginesYears = array();
foreach ($array as $value) {
$parts = explode(' ', $value, 2);
$year = (int)$parts[0];
$engine = $parts[1];
if (!isset($enginesYears[$engine])) {
$enginesYears[$engine] = array();
}
$enginesYears[$engine][] = $year;
}
ksort($enginesYears);
$array = array();
foreach ($enginesYears as $engine => $years) {
rsort($years);
foreach ($years as $year) {
$array[] = "$year $engine";
}
}
print_r($array);
Output:
Array
(
[0] => 2001 Jeep Cherokee
[1] => 2000 Jeep Cherokee
[2] => 1999 Jeep Cherokee
[3] => 1998 Jeep Cherokee
[4] => 1997 Jeep Cherokee
[5] => 1996 Jeep Cherokee
[6] => 1995 Jeep Cherokee
[7] => 1998 Jeep Grand Cherokee
[8] => 1997 Jeep Grand Cherokee
[9] => 1996 Jeep Grand Cherokee
[10] => 1995 Jeep Grand Cherokee
[11] => 2012 Jeep Liberty
[12] => 2011 Jeep Liberty
[13] => 2010 Jeep Liberty
[14] => 2009 Jeep Liberty
[15] => 2008 Jeep Liberty
[16] => 2007 Jeep Liberty
[17] => 2006 Jeep Liberty
[18] => 2005 Jeep Liberty
[19] => 2004 Jeep Liberty
[20] => 2003 Jeep Liberty
[21] => 2002 Jeep Liberty
[22] => 2006 Jeep Wrangler
[23] => 2005 Jeep Wrangler
[24] => 2004 Jeep Wrangler
[25] => 2003 Jeep Wrangler
[26] => 2002 Jeep Wrangler
[27] => 2001 Jeep Wrangler
[28] => 2000 Jeep Wrangler
[29] => 1999 Jeep Wrangler
[30] => 1998 Jeep Wrangler
[31] => 1997 Jeep Wrangler
[32] => 1995 Jeep Wrangler
)
The trick is to build this first:
Array
(
[Jeep Cherokee] => Array
(
[0] => 2001
[1] => 2000
[2] => 1999
[3] => 1998
[4] => 1997
[5] => 1996
[6] => 1995
)
[Jeep Grand Cherokee] => Array
(
[0] => 1998
[1] => 1997
[2] => 1996
[3] => 1995
)
[Jeep Liberty] => Array
(
[0] => 2012
[1] => 2011
[2] => 2010
[3] => 2009
[4] => 2008
[5] => 2007
[6] => 2006
[7] => 2005
[8] => 2004
[9] => 2003
[10] => 2002
)
[Jeep Wrangler] => Array
(
[0] => 2006
[1] => 2005
[2] => 2004
[3] => 2003
[4] => 2002
[5] => 2001
[6] => 2000
[7] => 1999
[8] => 1998
[9] => 1997
[10] => 1995
)
)
Ok, not 100% sure this is what you want, but if you want an array sorted first by Engine and second by Year, I might have a somewhat inelegant but working solution for you.
First, create a new associated ($res = array() ), and another 2D temporary array for each Engine name (you can go over the whole array to get a list of engine names, save the names you've already seen in $list, and build a temp array each time you encounter a new name). Put all elements of that engine in that array, so you get
[0] => 2012 Jeep Liberty
[7] => 2011 Jeep Liberty
[12] => 2010 Jeep Liberty
[15] => 2009 Jeep Liberty
[18] => 2008 Jeep Liberty
[22] => 2007 Jeep Liberty
[26] => 2006 Jeep Liberty
[44] => 2005 Jeep Liberty
[60] => 2004 Jeep Liberty
[73] => 2003 Jeep Liberty
[86] => 2002 Jeep Liberty
as $tempArray['Jeep Liberty'], for example (if Jeep Liberty was the first name you chose, since it had the highest year). Notice it is already sorted by year.
Now, remember $list from earlier, that has all names stored in their appearance order?
foreach($list as $value)
foreach(tempArray[value] as $key => $value2)
$res += array($key=>$value2.$value);
In the end, $res will be of the form
[0] => 2012 Jeep Liberty
[7] => 2011 Jeep Liberty
[12] => 2010 Jeep Liberty
[15] => 2009 Jeep Liberty
[18] => 2008 Jeep Liberty
[22] => 2007 Jeep Liberty
[26] => 2006 Jeep Liberty
[44] => 2005 Jeep Liberty
[60] => 2004 Jeep Liberty
[73] => 2003 Jeep Liberty
[86] => 2002 Jeep Liberty
[33] => 2006 Jeep Wrangler
[51] => 2005 Jeep Wrangler
[64] => 2004 Jeep Wrangler
[77] => 2003 Jeep Wrangler
[92] => 2002 Jeep Wrangler
[102] => 2001 Jeep Wrangler
[114] => 2000 Jeep Wrangler
[125] => 1999 Jeep Wrangler
[149] => 1998 Jeep Wrangler
[169] => 1997 Jeep Wrangler
[203] => 1995 Jeep Wrangler
[96] => 2001 Jeep Cherokee
[106] => 2000 Jeep Cherokee
[117] => 1999 Jeep Cherokee
[128] => 1998 Jeep Cherokee
[152] => 1997 Jeep Cherokee
[173] => 1996 Jeep Cherokee
[186] => 1995 Jeep Cherokee
[136] => 1998 Jeep Grand Cherokee
[159] => 1997 Jeep Grand Cherokee
[181] => 1996 Jeep Grand Cherokee
[193] => 1995 Jeep Grand Cherokee
Just as you want.
I think this is what you looking for:
<?php
$data[0] = '2012 Jeep Liberty';
$data[7] = '2011 Jeep Liberty';
$data[12] = '2010 Jeep Liberty';
$data[15] = '2009 Jeep Liberty';
$data[18] = '2008 Jeep Liberty';
$data[22] = '2007 Jeep Liberty';
$data[26] = '2006 Jeep Liberty';
$data[44] = '2005 Jeep Liberty';
$data[60] = '2004 Jeep Liberty';
$data[73] = '2003 Jeep Liberty';
$data[86] = '2002 Jeep Liberty';
$data[33] = '2006 Jeep Wrangler';
$data[51] = '2005 Jeep Wrangler';
$data[64] = '2004 Jeep Wrangler';
$data[77] = '2003 Jeep Wrangler';
$data[92] = '2002 Jeep Wrangler';
$data[102] = '2001 Jeep Wrangler ';
$data[114] = '2000 Jeep Wrangler';
$data[125] = '1999 Jeep Wrangler';
$data[149] = '1998 Jeep Wrangler';
$data[169] = '1997 Jeep Wrangler';
$data[203] = '1995 Jeep Wrangler';
$data[96] = '2001 Jeep Cherokee';
$data[106] = '2000 Jeep Cherokee';
$data[117] = '1999 Jeep Cherokee';
$data[128] = '1998 Jeep Cherokee';
$data[152] = '1997 Jeep Cherokee';
$data[173] = '1996 Jeep Cherokee';
$data[186] = '1995 Jeep Cherokee';
$data[136] = '1998 Jeep Grand Cherokee';
$data[159] = '1997 Jeep Grand Cherokee';
$data[181] = '1996 Jeep Grand Cherokee';
$data[193] = '1995 Jeep Grand Cherokee';
function my_cmp($value_1, $value_2)
{
$str_1_parts = explode(' ', $value_1);
$str_2_parts = explode(' ', $value_2);
$year_1 = (int)$str_1_parts[0];
$year_2 = (int)$str_2_parts[0];
if( $year_1 > $year_2 ) return 1;
if( $year_1 < $year_2 ) return -1;
unset( $str_1_parts[0] );
unset( $str_2_parts[0] );
return strcasecmp( implode(' ', $str_1_parts) , implode(' ', $str_2_parts));
}
usort($data,'my_cmp');
print_r( $data );