<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Rquadling's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 27 Jul 2008 08:35:10 GMT</pubDate>
    <description>DZone Snippets: Rquadling's Code Snippets</description>
    <item>
      <title>Sort multiple dimensional arrays by column without the need to extract the column data first.</title>
      <link>http://snippets.dzone.com/posts/show/2977</link>
      <description>A mechanism to sort multidimensional data by columns without the need to extract the column data first.&lt;br /&gt;&lt;br /&gt;The syntax is the same as array_multisort().&lt;br /&gt;&lt;br /&gt;You also have 3 additional parameters you can use:&lt;br /&gt;&lt;br /&gt;AMC_SORT_STRING_CASELESS to sort the strings case insensitively.&lt;br /&gt;AMC_LOSE_ASSOCIATION (the default behaviour) to lose the associations for the array.&lt;br /&gt;AMC_KEEP_ASSOCIATION to keep the associations for the array.&lt;br /&gt;&lt;br /&gt;If your array does not have associated indexes, then you can use column numbers. But watch out. If you also use PHP's constants like SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC or SORT_STRING, then these can be mixed up with column numbers.&lt;br /&gt;So, to remove this problem, I've created copies of these constants:&lt;br /&gt;AMC_SORT_ASC&lt;br /&gt;AMC_SORT_DESC&lt;br /&gt;AMC_SORT_REGULAR&lt;br /&gt;AMC_SORT_NUMERIC&lt;br /&gt;AMC_SORT_STRING&lt;br /&gt;&lt;br /&gt;Other than that, these function work together JUST like array_multisort but sorts using column(s) without the need to first extract the columns into individual arrays.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;/*&lt;br /&gt;(C) UK 2006 Richard Quadling&lt;br /&gt;&lt;br /&gt;This work is licensed under the Creative Commons Attribution 2.5 License.&lt;br /&gt;To view a copy of this license, visit http://creativecommons.org/licenses/by/2.5/ or send a letter to&lt;br /&gt;    Creative Commons,&lt;br /&gt;    543 Howard Street,&lt;br /&gt;    5th Floor,&lt;br /&gt;    San Francisco,&lt;br /&gt;    California,&lt;br /&gt;    94105, USA.&lt;br /&gt;&lt;br /&gt;Version History&lt;br /&gt;&lt;br /&gt;2006/09/20&lt;br /&gt;Removed reliance on PHP's constants as using column numbers conflicted with these constants.&lt;br /&gt;Use AMC_SORT_xxx rather than SORT_xxx.&lt;br /&gt;&lt;br /&gt;2006/08/23&lt;br /&gt;Added CC license&lt;br /&gt;Added notice and error for parameters&lt;br /&gt;&lt;br /&gt;2006/08/22&lt;br /&gt;Fixed local defines to be well out of the way of the ones used by PHP.&lt;br /&gt;&lt;br /&gt;2006/08/07&lt;br /&gt;Created this code based upon work done by KES (http://www.php.net/manual/en/function.array-multisort.php#68452)&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;// AMC defines for keeping association.&lt;br /&gt;define ('AMC_LOSE_ASSOCIATION', 'AMC10001');&lt;br /&gt;define ('AMC_KEEP_ASSOCIATION', 'AMC10002');&lt;br /&gt;&lt;br /&gt;// AMC defines for the global array.&lt;br /&gt;define ('AMC_SORT_ORDER', 'AMC10003');&lt;br /&gt;define ('AMC_SORT_TYPE', 'AMC10004');&lt;br /&gt;&lt;br /&gt;// AMC defines for the sort order.&lt;br /&gt;define ('AMC_SORT_ASC', 'AMC10005');&lt;br /&gt;define ('AMC_SORT_DESC', 'AMC10006');&lt;br /&gt;&lt;br /&gt;// AMC defines for sorting type.&lt;br /&gt;define ('AMC_SORT_REGULAR', 'AMC10007');&lt;br /&gt;define ('AMC_SORT_NUMERIC', 'AMC10008');&lt;br /&gt;define ('AMC_SORT_STRING', 'AMC10009');&lt;br /&gt;define ('AMC_SORT_STRING_CASELESS', 'AMC10010');&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;  * bool array_multisort_column ( array ar1 [, mixed arg [, mixed ... [, array ...]]] )&lt;br /&gt;  **/&lt;br /&gt;function array_multisort_column(array &amp;$a_data, $m_mixed1)&lt;br /&gt;    {&lt;br /&gt;    // Get the parameters and the number of parameters.&lt;br /&gt;    $a_Args = func_get_args();&lt;br /&gt;    $i_Args = func_num_args();&lt;br /&gt;&lt;br /&gt;    // Define a global empty array for the comparison function.&lt;br /&gt;    $GLOBALS['a_AMC_ordering'] = array();&lt;br /&gt;&lt;br /&gt;    // Get the list of columns.&lt;br /&gt;    $a_Columns = array_keys(reset($a_data));&lt;br /&gt;&lt;br /&gt;    // Assume association is NOT kept&lt;br /&gt;    $b_KeepAssociation = False;&lt;br /&gt;&lt;br /&gt;    // Process the parameter list, extracting columns and any applicable settings.&lt;br /&gt;    for($i_Arg = 1 ; $i_Arg &lt; $i_Args ; )&lt;br /&gt;        {&lt;br /&gt;        // Initially we only want to look at columns.&lt;br /&gt;        if (in_array($a_Args[$i_Arg], $a_Columns))&lt;br /&gt;            {&lt;br /&gt;            // Track the column.&lt;br /&gt;            $s_Column = $a_Args[$i_Arg];&lt;br /&gt;&lt;br /&gt;            // Add the column with default settings to the global array.&lt;br /&gt;            $GLOBALS['a_AMC_ordering'][$a_Args[$i_Arg]] = array&lt;br /&gt;                (&lt;br /&gt;                AMC_SORT_ORDER =&gt; AMC_SORT_ASC,&lt;br /&gt;                AMC_SORT_TYPE =&gt; AMC_SORT_REGULAR,&lt;br /&gt;                );&lt;br /&gt;&lt;br /&gt;            // While there are more parameters to process is the next one a controller rather than a column.&lt;br /&gt;            while&lt;br /&gt;                (&lt;br /&gt;&lt;br /&gt;                // There IS a next parameter.&lt;br /&gt;                isset($a_Args[$i_Arg + 1]) &amp;&amp; &lt;br /&gt;&lt;br /&gt;                // It is a controller.&lt;br /&gt;                in_array&lt;br /&gt;                    (&lt;br /&gt;                    $a_Args[$i_Arg + 1], &lt;br /&gt;                    array&lt;br /&gt;                        (&lt;br /&gt;                        AMC_KEEP_ASSOCIATION,&lt;br /&gt;                        AMC_LOSE_ASSOCIATION,&lt;br /&gt;                        AMC_SORT_STRING_CASELESS,&lt;br /&gt;                        AMC_SORT_ASC,&lt;br /&gt;                        AMC_SORT_DESC,&lt;br /&gt;                        AMC_SORT_NUMERIC,&lt;br /&gt;                        AMC_SORT_REGULAR,&lt;br /&gt;                        AMC_SORT_STRING,&lt;br /&gt;                        ), &lt;br /&gt;                    True&lt;br /&gt;                    )&lt;br /&gt;&lt;br /&gt;                )&lt;br /&gt;                {&lt;br /&gt;                // Deal with column sorting order.&lt;br /&gt;                if (&lt;br /&gt;                    in_array&lt;br /&gt;                        (&lt;br /&gt;                        $a_Args[$i_Arg + 1], &lt;br /&gt;                        array&lt;br /&gt;                            (&lt;br /&gt;                            AMC_SORT_ASC, &lt;br /&gt;                            AMC_SORT_DESC&lt;br /&gt;                            ), &lt;br /&gt;                        True&lt;br /&gt;                        )&lt;br /&gt;                    )&lt;br /&gt;                    {&lt;br /&gt;                    $GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_ORDER] = $a_Args[$i_Arg + 1];&lt;br /&gt;                    }&lt;br /&gt;                // Deal with column sorting type.&lt;br /&gt;                elseif (&lt;br /&gt;                    in_array&lt;br /&gt;                        (&lt;br /&gt;                        $a_Args[$i_Arg + 1], &lt;br /&gt;                        array&lt;br /&gt;                            (&lt;br /&gt;                            AMC_SORT_REGULAR, &lt;br /&gt;                            AMC_SORT_NUMERIC, &lt;br /&gt;                            AMC_SORT_STRING, &lt;br /&gt;                            AMC_SORT_STRING_CASELESS&lt;br /&gt;                            ), &lt;br /&gt;                        True&lt;br /&gt;                        )&lt;br /&gt;                    )&lt;br /&gt;                    {&lt;br /&gt;                    $GLOBALS['a_AMC_ordering'][$s_Column][AMC_SORT_TYPE] = $a_Args[$i_Arg + 1];&lt;br /&gt;                    }&lt;br /&gt;                // Deal with array association.&lt;br /&gt;                else&lt;br /&gt;                    {&lt;br /&gt;                    $b_KeepAssociation = (AMC_KEEP_ASSOCIATION == $a_Args[$i_Arg + 1]);&lt;br /&gt;                    }&lt;br /&gt;                // Take the next argument out of the picture.&lt;br /&gt;                ++$i_Arg;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        // Allow array association to be defined.&lt;br /&gt;        elseif (&lt;br /&gt;            in_array&lt;br /&gt;                (&lt;br /&gt;                $a_Args[$i_Arg], &lt;br /&gt;                array&lt;br /&gt;                    (&lt;br /&gt;                    AMC_KEEP_ASSOCIATION, &lt;br /&gt;                    AMC_LOSE_ASSOCIATION&lt;br /&gt;                    ), &lt;br /&gt;                True&lt;br /&gt;                )&lt;br /&gt;            )&lt;br /&gt;            {&lt;br /&gt;            $b_KeepAssociation = (AMC_KEEP_ASSOCIATION == $a_Args[$i_Arg]);&lt;br /&gt;            }&lt;br /&gt;        // Ignore sort options as they are not in the right place to be understood.&lt;br /&gt;        elseif (&lt;br /&gt;            in_array&lt;br /&gt;                (&lt;br /&gt;                $a_Args[$i_Arg], &lt;br /&gt;                array&lt;br /&gt;                    (&lt;br /&gt;                    AMC_SORT_REGULAR, &lt;br /&gt;                    AMC_SORT_NUMERIC, &lt;br /&gt;                    AMC_SORT_STRING, &lt;br /&gt;                    AMC_SORT_STRING_CASELESS&lt;br /&gt;                    ), &lt;br /&gt;                True&lt;br /&gt;                )&lt;br /&gt;            )&lt;br /&gt;            {&lt;br /&gt;            trigger_error("Parameter $i_Arg of '{$a_Args[$i_Arg]}' is not applicable and has been ignored.", E_USER_NOTICE);&lt;br /&gt;            }&lt;br /&gt;        // Whatever is left is an error.&lt;br /&gt;        else&lt;br /&gt;            {&lt;br /&gt;            trigger_error("Requested column of '{$a_Args[$i_Arg]}' is not present in the supplied array.", E_USER_ERROR);&lt;br /&gt;            }&lt;br /&gt;        // Get the next argument.&lt;br /&gt;        ++$i_Arg;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    // Determine which usort mechanism (with or without associations).&lt;br /&gt;    $s_Sorter = ($b_KeepAssociation ? 'uasort' : 'usort');&lt;br /&gt;&lt;br /&gt;    // Sort the data and get the result.&lt;br /&gt;    $b_Result = $s_Sorter($a_data, 'array_multisort_column_cmp');&lt;br /&gt;&lt;br /&gt;    // Remove the temporary global array.&lt;br /&gt;    unset($GLOBALS['a_AMC_ordering']);&lt;br /&gt;&lt;br /&gt;    // Return the results&lt;br /&gt;    return $b_Result;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt;  * int array_multisort_column_cmp(array a_left, array a_right)&lt;br /&gt;  **/&lt;br /&gt;function array_multisort_column_cmp(array &amp;$a_left, array &amp;$a_right)&lt;br /&gt;    {&lt;br /&gt;    // Assume that the entries are the same.&lt;br /&gt;    $i_Result = 0;&lt;br /&gt;&lt;br /&gt;    // Process each column defined in the global array.&lt;br /&gt;    foreach($GLOBALS['a_AMC_ordering'] as $s_Column =&gt; $a_ColumnData)&lt;br /&gt;        {&lt;br /&gt;        // Handle the different sort types.&lt;br /&gt;        switch ($a_ColumnData[AMC_SORT_TYPE])&lt;br /&gt;            {&lt;br /&gt;            // Numeric.&lt;br /&gt;            case AMC_SORT_NUMERIC :&lt;br /&gt;                $i_ColumnCompareResult = &lt;br /&gt;                    ((intval($a_left[$s_Column]) == intval($a_right[$s_Column])) &lt;br /&gt;                    ? &lt;br /&gt;                        0 &lt;br /&gt;                    : &lt;br /&gt;                        ((intval($a_left[$s_Column]) &lt; intval($a_right[$s_Column])) &lt;br /&gt;                        ? &lt;br /&gt;                            -1 &lt;br /&gt;                        : &lt;br /&gt;                            1&lt;br /&gt;                        )&lt;br /&gt;                    );&lt;br /&gt;                break;&lt;br /&gt;            // Case sensitive strings.&lt;br /&gt;            case AMC_SORT_STRING :&lt;br /&gt;                $i_ColumnCompareResult = strcmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);&lt;br /&gt;                break;&lt;br /&gt;            // Case insensitive strings.&lt;br /&gt;            case AMC_SORT_STRING_CASELESS :&lt;br /&gt;                $i_ColumnCompareResult = strcasecmp((string)$a_left[$s_Column], (string)$a_right[$s_Column]);&lt;br /&gt;                break;&lt;br /&gt;            // Regular sorting.&lt;br /&gt;            case AMC_SORT_REGULAR :&lt;br /&gt;            default :&lt;br /&gt;                $i_ColumnCompareResult = &lt;br /&gt;                    (($a_left[$s_Column] == $a_right[$s_Column]) &lt;br /&gt;                    ? &lt;br /&gt;                        0 &lt;br /&gt;                    : &lt;br /&gt;                        (($a_left[$s_Column] &lt; $a_right[$s_Column]) &lt;br /&gt;                        ? &lt;br /&gt;                            -1 &lt;br /&gt;                        : &lt;br /&gt;                            1&lt;br /&gt;                        )&lt;br /&gt;                    );&lt;br /&gt;                break;&lt;br /&gt;            }&lt;br /&gt;        // Is the column in the two arrays the same?&lt;br /&gt;        if (0 == $i_ColumnCompareResult)&lt;br /&gt;            {&lt;br /&gt;            // Continue with the next column.&lt;br /&gt;            continue;&lt;br /&gt;            }&lt;br /&gt;        // Are we sorting descending?&lt;br /&gt;        $i_Result = $i_ColumnCompareResult * (($a_ColumnData[AMC_SORT_ORDER] == AMC_SORT_DESC) ? -1 : 1);&lt;br /&gt;&lt;br /&gt;        // As there is a difference, we do not need to continue with the remaining columns.&lt;br /&gt;        break;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    // Return the result.&lt;br /&gt;    return $i_Result;&lt;br /&gt;    }&lt;br /&gt;?&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 06 Nov 2006 18:36:27 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2977</guid>
      <author>RQuadling (Richard Quadling)</author>
    </item>
  </channel>
</rss>
