【问题标题】:Sort 2nd nested array by value in 3rd with php使用php按第三个值对第二个嵌套数组进行排序
【发布时间】:2014-04-06 23:16:52
【问题描述】:

需要用 php 对第二个嵌套数组按值 n 第三个进行排序; '开始时间'。思考也许 usort 是关键。发布 @week @day @class 的嵌套数组以及我一直在尝试变体的 usort 调用和函数。

Array
(
  [Sunday] => Array
    (
        [0] => Array
            (
                [Class Name] => Fun Class
                [Instructor] => Fun Teacher
                [Class Type] => Yoga Stretches
                [Start Time] => 1899-12-30T17:00:00
                [End Time] => 1899-12-30T18:15:00
                [Day Name] => Sunday
            )

        [1] => Array
            (
                [Class Name] => Another Fun Class
                [Instructor] => Same Fun Teacher
                [Class Type] => Relaxation
                [Start Time] => 1899-12-30T18:30:00
                [End Time] => 1899-12-30T19:45:00
                [Day Name] => Sunday
            )

        [2] => Array
            (
                [Class Name] => Hot Yoga without Cold
                [Instructor] => Dave the Flexible
                [Class Type] => Hot Hot Yoga
                [Start Time] => 1899-12-30T09:00:00
                [End Time] => 1899-12-30T10:30:00
                [Day Name] => Sunday
            )
    )
    [Monday] => Array
    (
        [0] => Array
            (
                [Class Name] => Mellow Chill Hang
                [Instructor] => Guru Awesome
                [Class Type] => Yoga Namaste
                [Start Time] => 1899-12-30T12:00:00
                [End Time] => 1899-12-30T13:00:00
                [Day Name] => Monday
            )
   )
)

已经尝试过(变体):

foreach ($week_schedule as $day)//$week_schedule = the outer array
    {
     for($j=count($week_schedule);$j>=0;$j--)
         usort($day,'sortTimes');
}

function sortTimes( $a, $b ) {
    return strtotime($a["Start Time"]) - strtotime($b["Start Time"]);
 }

已尝试使用单个 foreach 提取值 ($day => $class)。 我敢打赌这最终不会需要太多代码。

【问题讨论】:

    标签: php arrays sorting nested usort


    【解决方案1】:

    尝试使用 array_map 进入嵌套元素,并且您的 Start Time 有一个我认为不能与 strtotime 一起使用的“T”字符,因此我将其删除:

    function custom_map( $array ) {
        usort( $array, function( $a, $b ) {
            return ($a['Start Time']<$b['Start Time'])? -1 : 1;
        });
        return $array;
    }
    
    $new_array = array_map( "custom_map", $week_schedule );
    
    var_dump($new_array);
    

    Demo

    说明:

    由于您有兴趣了解其工作原理,因此我自己进行了一些研究并提出了以下解释:

    首先,你应该知道array_map()和usort()是干什么用的。

    array_map() 来自 PHP 文档:

    array_map() 返回一个包含 array1 的所有元素的数组 在将回调函数应用于每个之后。

    语法:

    array array_map ( callable $callback , array $array1 [, array $... ] )
    

    简单来说,array_map() 会将数组的每个元素传递给您指定的回调函数。它返回一个数组(具有更改的值,您在 that 回调函数中完成)。

    现在 usort(),

    usort() 来自 PHP 文档:

    此函数将使用用户提供的比较函数按数组的值对数组进行排序。如果您要排序的数组需要按照一些重要的标准进行排序,您应该使用此函数。

    语法:

    bool usort ( array &$array , callable $value_compare_func )
    

    所以,usort() 基本上比较每个数组元素,以便按正确的顺序对其进行排序。您在此处看到的行:

    return ($a['Start Time']<$b['Start Time'])? -1 : 1;
    

    基本上翻译为:

     if $a['Start Time'] is lesser than $b['Start Time'], then return -1 so
     that $a can come before $b
    

    有价值观:

    $a['Start Time'] = '1899-12-30T09:00:00'; //3rd element
    $b['Start Time'] = '1899-12-30T17:00:00'; //1st element
    

    现在很明显,作为第三个元素的 $a 小于第一个元素 $b,因此 $a 将被定位在它之前。 usort() 从头到尾检查每个组合以进行排序。

    现在,回到 array_map(),我们使用它的原因是因为你有嵌套数组。

    array_map() 的实际作用是将你所有的 @days 传递给 usort。然后 usort 获取您所有的 @class 并相应地进行排序。如果您看到以下演示,其中您的 @weeks 仅在 @days 和 @class 存在的情况下被取出,则上述代码将不起作用,并且会因为您试图遍历 2 而导致找不到“开始时间”的错误仅存在 1 时的嵌套数组:

    Demo

    对于上述结构,正确的方法是不使用array_map,直接实现usort:

    Demo

    【讨论】:

    • 非常感谢@I Can Has Cheezburger。当然有效。在我的服务器(php 5.5.3)上,日期时间('开始时间')字段中的'T'也可以使用。 usort 函数如何知道要在三个数组(@week、@day、@classes)中的哪个数组中查找“开始时间”?它是否会进一步搜索深度嵌套的数组,直到找到与“开始时间”匹配的内容
    • 我也想清楚地解释一下 usort 正在做什么。假设数组中有四个元素;如果测试为真,它会将第一个元素与其他所有元素进行比较并减少它的数字键吗?这会自动增加以前在数组中那个位置的键吗?
    • @MikeiLL 我已经在上面的答案中添加了解释,希望它能消除你的一些疑问。
    • 很好的解释。非常感谢你。所以对于array_map,array1中的“每个元素”是一个array_day,通过比较array_class中的时间字段,由usort重新排列array_class的元素。递减适用于array_class 在array_day 中的放置。我知道了。美丽的。再次感谢。
    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多