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

时间:2016-01-29 21:29:04

标签: php sorting multidimensional-array

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

  1. 星期几
  2. 一日餐(早餐/午餐/晚餐)
  3. 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
    )
    

3 个答案:

答案 0 :(得分:0)

试试这个解决方案。当然可以使用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>");

答案 1 :(得分:0)

非常有趣的问题!

我试图从中抽象出来创建一个泛型函数,通过给定的标准数组来排序多维数组。

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

所以,在你的情况下,你必须这样做:

$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 demo 中看到结果(我已经在你的数组中添加了一个假项目,以便在存在不匹配时查看行为标准)。

功能:

/*  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;
}

答案 2 :(得分:0)

只需将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]);
        }
    }
}