使用 2 个自定义条件对多维关联数组进行排序:(按星期几和用餐时间进餐)


Sorting Multidimensional Associative Array with 2 custom criteria: (Meals by Day of Week and Meal Time)

>我有一个多维数组,需要按两个自定义条件按顺序排序:

  1. 星期几
  2. 一日餐(早餐/午餐/晚餐(

array_multisort()uksort()的文档已经让我各自完成了一半,但我无法将它们有意义地放在一起。谢谢你的时间

Array
(
    [name] => hashbrowns
    [day] => monday
    [mealTime] => breakfast
)
Array
(
    [name] => Steak
    [day] => monday
    [mealTime] => dinner
)
Array
(
    [name] => Avacados
    [day] => tuesday
    [mealTime] => dinner
)
Array
(
    [name] => Peaches
    [day] => tuesday
    [mealTime] => lunch
)
Array
(
    [name] => Sammich
    [day] => monday
    [mealTime] => lunch
)
Array
(
    [name] => Kale & Sadness
    [day] => tuesday
    [mealTime] => breakfast
)

所需的输出示例:

Array
(
    [name] => hashbrowns
    [day] => monday
    [mealTime] => breakfast
)
Array
(
    [name] => Sammich
    [day] => monday
    [mealTime] => lunch
)
Array
(
    [name] => Steak
    [day] => monday
    [mealTime] => dinner
)
Array
(
    [name] => Kale & Sadness
    [day] => tuesday
    [mealTime] => breakfast
)
Array
(
    [name] => Peaches
    [day] => tuesday
    [mealTime] => lunch
)
Array
(
    [name] => Avacados
    [day] => tuesday
    [mealTime] => dinner
)

试试这个解决方案。当然,它可以使用php函数来完成,但是发生在您身上的事情似乎有效。

$data = array(
array("name" => "Otra cosa","day" => "thursday","mealTime" => "dinner"),
array("name" => "hashbrowns","day" => "monday","mealTime" => "breakfast"),
array("name" => "Steak","day" => "monday","mealTime" => "dinner"),
array("name" => "Avacados","day" => "tuesday","mealTime" => "dinner"),
array("name" => "Cuchu","day" => "monday","mealTime" => "breakfast"),
array("name" => "Avacados 2","day" => "monday","mealTime" => "lunch"));

$day = array("monday" => 0, "tuesday" => 1, "wednesday" => 2, "thursday" => 3, "friday" => 4, "saturday" => 5, "sunday" => 6);
$mealTime = array("breakfast" =>0, "lunch" =>1, "dinner" => 2);

$result = array();
foreach($data as $values) {
    $d = $day[$values["day"]];
    $mt = $mealTime[$values["mealTime"]];
    if(!isset($result[$d])) {
        $result[$d] = array();
    }
    if(!isset($result[$d][$mt])) {
        $result[$d][$mt] = array();
    }
    $result[$d][$mt][] = $values;
    ksort($result[$d]);
}
ksort($result);
$_result = array();
foreach($result as $r) {
    foreach($r as $_r) {
        foreach($_r as $__r) {
            $_result[] = $__r;
        }
    }
}
return $_result;
//print_r("<pre>");
//print_r($_result);
//print_r("</pre>");

非常有趣的问题!

我试图从中抽象出来创建一个泛型函数,以按给定的条件数组对多维数组进行排序。

结果是下面的函数,它的第一个参数是一个多维数组,如问题中提供的数组,第二个参数是一个关联数组的多维数组,每个数组都有键作为键(即"天"(和所需的排序值作为值(即'星期一','星期二',...(。您可以通过一个、两个或多个条件。如果行与条件不匹配,则追加在结果数组的末尾;如果一行具有键条件,但它们的值不在条件值中(即具有键='天',值='每天'(,则相同。

因此,在您的情况下,您必须以这种方式执行此操作:

$menu = //Your array//
$criteria = array
(
    'day' => explode( ',', 'monday,tuesday,wednesday,thursday,friday,saturday,sunday' ), 
    'mealTime' => explode( ',', 'breakfast,lunch,dinner' )
);
$result = sortArrayByCriteria( $menu, $criteria );

您可以在此 eval.in 演示中看到结果(我已将一个假项目添加到您的数组中,以查看存在不匹配条件时的行为(。

该函数:

/*  Sort a multidimensional array by an array of criteria which keys are 
 *  the key to sort and values are the sort criteria
 *  Unmatched values are appended at the end of array.
 *
 *  @param  array  $array     array to be sorted
 *  @param  array  $criteria  array of criteria
 *
 *  @return array  sorted array
 */
function sortArrayByCriteria( $array, $criteria ) 
{
    # Extract current (last) criteria and reduce criteria array:
    $sortValues = end( $criteria );
    $sortKey    = key( $criteria );
    array_pop( $criteria );
    $sorted = $unsorted = array();
    foreach( $sortValues as $compare )
    {
        $key = 0;
        # Check each array:
        while( $key < count( $array ) )
        {
            # If array row doesn't have key to sort, add-it to unsorted array:
            if( !isset($array[$key][$sortKey]) )
            { $unsorted[] = reset( array_splice( $array, $key, 1 ) ); }
            else
            {
                # If value==current comparisation value, add-it to sorted:
                if( $array[$key][$sortKey] == $compare ) 
                { $sorted[] = reset( array_splice( $array, $key, 1 ) ); }
                # If value doesn't is in the comparisation values, add-it to unsorted:
                elseif( !in_array( $array[$key][$sortKey], $sortValues ) )
                { $unsorted[] = reset( array_splice( $array, $key, 1 ) ); }
                # Otherwise increment index pointer:
                else $key++;
            }
        }
    }
    # Merge sorted and unsorted values in one array:
    $retval = array_merge( $sorted, $unsorted );
    # If there are others criteria, performs a self-call:
    if( count( $criteria ) ) $retval = sortArrayByCriteria( $retval, $criteria );
    return $retval;
}

考虑简单地将mealnumberdaynumber添加到主数组中,使用 array_multisort() 按这些数值字段排序,然后将它们从数组中删除:

// INITIALIZE SORT ARRAYS
$mealarr = array();
$dayarr = array();
// APPEND TO MAIN AND SORT ARRAYS, NEW MEALNUMEBR AND DAYNUMBER ELEMENTS
for($i=0; $i<sizeof($breakfast); $i++){
    foreach ($breakfast[$i] as $key => $value) {               
         switch ($value) {                
             case "breakfast":   $breakfast[$i]['mealnumber'] = 1; $mealarr[] = 1; break;
             case "lunch":       $breakfast[$i]['mealnumber'] = 2; $mealarr[] = 2; break;
             case "dinner":      $breakfast[$i]['mealnumber'] = 3; $mealarr[] = 3; break;            
             case "monday":      $breakfast[$i]['daynumber'] = 1; $dayarr[] = 1; break;
             case "tuesday":     $breakfast[$i]['daynumber'] = 2; $dayarr[] = 2; break;
             case "wednesday":   $breakfast[$i]['daynumber'] = 3; $dayarr[] = 3; break;                
             case "thursday":    $breakfast[$i]['daynumber'] = 4; $dayarr[] = 4; break;
             case "friday":      $breakfast[$i]['daynumber'] = 5; $dayarr[] = 5; break;
             case "saturday":    $breakfast[$i]['daynumber'] = 6; $dayarr[] = 6; break;
             case "sunday":      $breakfast[$i]['daynumber'] = 7; $dayarr[] = 7; break;   
         }        
    }    
}
// SORT MAIN ARRAY
array_multisort($dayarr, SORT_ASC, $mealarr, SORT_ASC, $data); 
// REMOVE MEALNUMBER AND DAYNUMBER ELEMENTS
for($i=0; $i<sizeof($data); $i++){
    foreach ($data[$i] as $key => $value) {
        if ($key=='mealnumber' or $key=='daynumber') {
            unset($data[$i][$key]);
        }
    }
}